@aceshooting/lyra-ui 3.7.0 → 3.9.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 (1323) hide show
  1. package/README.md +109 -3
  2. package/custom-elements.json +90743 -41052
  3. package/dist/components/activity-feed/activity-feed.class.d.ts +123 -0
  4. package/dist/components/activity-feed/activity-feed.class.d.ts.map +1 -0
  5. package/dist/components/activity-feed/activity-feed.class.js +300 -0
  6. package/dist/components/activity-feed/activity-feed.class.js.map +1 -0
  7. package/dist/components/activity-feed/activity-feed.d.ts +2 -0
  8. package/dist/components/activity-feed/activity-feed.d.ts.map +1 -0
  9. package/dist/components/activity-feed/activity-feed.js +5 -0
  10. package/dist/components/activity-feed/activity-feed.js.map +1 -0
  11. package/dist/components/activity-feed/activity-feed.styles.d.ts +2 -0
  12. package/dist/components/activity-feed/activity-feed.styles.d.ts.map +1 -0
  13. package/dist/components/activity-feed/activity-feed.styles.js +147 -0
  14. package/dist/components/activity-feed/activity-feed.styles.js.map +1 -0
  15. package/dist/components/animation/animation.class.d.ts +12 -0
  16. package/dist/components/animation/animation.class.d.ts.map +1 -1
  17. package/dist/components/animation/animation.class.js +47 -7
  18. package/dist/components/animation/animation.class.js.map +1 -1
  19. package/dist/components/app-rail/app-rail.class.d.ts +19 -3
  20. package/dist/components/app-rail/app-rail.class.d.ts.map +1 -1
  21. package/dist/components/app-rail/app-rail.class.js +34 -12
  22. package/dist/components/app-rail/app-rail.class.js.map +1 -1
  23. package/dist/components/app-rail/app-rail.styles.d.ts.map +1 -1
  24. package/dist/components/app-rail/app-rail.styles.js +19 -11
  25. package/dist/components/app-rail/app-rail.styles.js.map +1 -1
  26. package/dist/components/artifact-panel/artifact-panel.class.d.ts +100 -0
  27. package/dist/components/artifact-panel/artifact-panel.class.d.ts.map +1 -0
  28. package/dist/components/artifact-panel/artifact-panel.class.js +254 -0
  29. package/dist/components/artifact-panel/artifact-panel.class.js.map +1 -0
  30. package/dist/components/artifact-panel/artifact-panel.d.ts +2 -0
  31. package/dist/components/artifact-panel/artifact-panel.d.ts.map +1 -0
  32. package/dist/components/artifact-panel/artifact-panel.js +5 -0
  33. package/dist/components/artifact-panel/artifact-panel.js.map +1 -0
  34. package/dist/components/artifact-panel/artifact-panel.styles.d.ts +2 -0
  35. package/dist/components/artifact-panel/artifact-panel.styles.d.ts.map +1 -0
  36. package/dist/components/artifact-panel/artifact-panel.styles.js +97 -0
  37. package/dist/components/artifact-panel/artifact-panel.styles.js.map +1 -0
  38. package/dist/components/attachment-chip/attachment-chip.class.d.ts +4 -2
  39. package/dist/components/attachment-chip/attachment-chip.class.d.ts.map +1 -1
  40. package/dist/components/attachment-chip/attachment-chip.class.js +10 -5
  41. package/dist/components/attachment-chip/attachment-chip.class.js.map +1 -1
  42. package/dist/components/attachment-chip/attachment-chip.styles.d.ts.map +1 -1
  43. package/dist/components/attachment-chip/attachment-chip.styles.js +7 -2
  44. package/dist/components/attachment-chip/attachment-chip.styles.js.map +1 -1
  45. package/dist/components/attachment-trigger/attachment-trigger.class.d.ts +17 -12
  46. package/dist/components/attachment-trigger/attachment-trigger.class.d.ts.map +1 -1
  47. package/dist/components/attachment-trigger/attachment-trigger.class.js +28 -8
  48. package/dist/components/attachment-trigger/attachment-trigger.class.js.map +1 -1
  49. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts.map +1 -1
  50. package/dist/components/attachment-trigger/attachment-trigger.styles.js +11 -0
  51. package/dist/components/attachment-trigger/attachment-trigger.styles.js.map +1 -1
  52. package/dist/components/audio-visualizer/audio-visualizer.class.d.ts +111 -0
  53. package/dist/components/audio-visualizer/audio-visualizer.class.d.ts.map +1 -0
  54. package/dist/components/audio-visualizer/audio-visualizer.class.js +435 -0
  55. package/dist/components/audio-visualizer/audio-visualizer.class.js.map +1 -0
  56. package/dist/components/audio-visualizer/audio-visualizer.d.ts +2 -0
  57. package/dist/components/audio-visualizer/audio-visualizer.d.ts.map +1 -0
  58. package/dist/components/audio-visualizer/audio-visualizer.js +5 -0
  59. package/dist/components/audio-visualizer/audio-visualizer.js.map +1 -0
  60. package/dist/components/audio-visualizer/audio-visualizer.styles.d.ts +2 -0
  61. package/dist/components/audio-visualizer/audio-visualizer.styles.d.ts.map +1 -0
  62. package/dist/components/audio-visualizer/audio-visualizer.styles.js +20 -0
  63. package/dist/components/audio-visualizer/audio-visualizer.styles.js.map +1 -0
  64. package/dist/components/av-player/av-player.class.d.ts +215 -0
  65. package/dist/components/av-player/av-player.class.d.ts.map +1 -0
  66. package/dist/components/av-player/av-player.class.js +590 -0
  67. package/dist/components/av-player/av-player.class.js.map +1 -0
  68. package/dist/components/av-player/av-player.d.ts +2 -0
  69. package/dist/components/av-player/av-player.d.ts.map +1 -0
  70. package/dist/components/av-player/av-player.js +36 -0
  71. package/dist/components/av-player/av-player.js.map +1 -0
  72. package/dist/components/av-player/av-player.styles.d.ts +2 -0
  73. package/dist/components/av-player/av-player.styles.d.ts.map +1 -0
  74. package/dist/components/av-player/av-player.styles.js +109 -0
  75. package/dist/components/av-player/av-player.styles.js.map +1 -0
  76. package/dist/components/avatar-group/avatar-group.class.d.ts +7 -2
  77. package/dist/components/avatar-group/avatar-group.class.d.ts.map +1 -1
  78. package/dist/components/avatar-group/avatar-group.class.js +19 -2
  79. package/dist/components/avatar-group/avatar-group.class.js.map +1 -1
  80. package/dist/components/badge/tag.class.d.ts +4 -1
  81. package/dist/components/badge/tag.class.d.ts.map +1 -1
  82. package/dist/components/badge/tag.class.js +4 -1
  83. package/dist/components/badge/tag.class.js.map +1 -1
  84. package/dist/components/branch-picker/branch-picker.class.d.ts +69 -0
  85. package/dist/components/branch-picker/branch-picker.class.d.ts.map +1 -0
  86. package/dist/components/branch-picker/branch-picker.class.js +151 -0
  87. package/dist/components/branch-picker/branch-picker.class.js.map +1 -0
  88. package/dist/components/branch-picker/branch-picker.d.ts +3 -0
  89. package/dist/components/branch-picker/branch-picker.d.ts.map +1 -0
  90. package/dist/components/branch-picker/branch-picker.js +6 -0
  91. package/dist/components/branch-picker/branch-picker.js.map +1 -0
  92. package/dist/components/branch-picker/branch-picker.styles.d.ts +2 -0
  93. package/dist/components/branch-picker/branch-picker.styles.d.ts.map +1 -0
  94. package/dist/components/branch-picker/branch-picker.styles.js +64 -0
  95. package/dist/components/branch-picker/branch-picker.styles.js.map +1 -0
  96. package/dist/components/browser-frame/browser-frame.class.d.ts +70 -0
  97. package/dist/components/browser-frame/browser-frame.class.d.ts.map +1 -0
  98. package/dist/components/browser-frame/browser-frame.class.js +196 -0
  99. package/dist/components/browser-frame/browser-frame.class.js.map +1 -0
  100. package/dist/components/browser-frame/browser-frame.d.ts +2 -0
  101. package/dist/components/browser-frame/browser-frame.d.ts.map +1 -0
  102. package/dist/components/browser-frame/browser-frame.js +5 -0
  103. package/dist/components/browser-frame/browser-frame.js.map +1 -0
  104. package/dist/components/browser-frame/browser-frame.styles.d.ts +2 -0
  105. package/dist/components/browser-frame/browser-frame.styles.d.ts.map +1 -0
  106. package/dist/components/browser-frame/browser-frame.styles.js +88 -0
  107. package/dist/components/browser-frame/browser-frame.styles.js.map +1 -0
  108. package/dist/components/button/button.class.d.ts +29 -4
  109. package/dist/components/button/button.class.d.ts.map +1 -1
  110. package/dist/components/button/button.class.js +40 -7
  111. package/dist/components/button/button.class.js.map +1 -1
  112. package/dist/components/button/button.styles.d.ts.map +1 -1
  113. package/dist/components/button/button.styles.js +17 -0
  114. package/dist/components/button/button.styles.js.map +1 -1
  115. package/dist/components/calendar/calendar.class.d.ts +14 -2
  116. package/dist/components/calendar/calendar.class.d.ts.map +1 -1
  117. package/dist/components/calendar/calendar.class.js +41 -8
  118. package/dist/components/calendar/calendar.class.js.map +1 -1
  119. package/dist/components/calendar/calendar.styles.d.ts.map +1 -1
  120. package/dist/components/calendar/calendar.styles.js +9 -4
  121. package/dist/components/calendar/calendar.styles.js.map +1 -1
  122. package/dist/components/calendar-viewer/calendar-viewer.class.d.ts.map +1 -1
  123. package/dist/components/calendar-viewer/calendar-viewer.class.js +2 -1
  124. package/dist/components/calendar-viewer/calendar-viewer.class.js.map +1 -1
  125. package/dist/components/callout/callout.class.d.ts +5 -1
  126. package/dist/components/callout/callout.class.d.ts.map +1 -1
  127. package/dist/components/callout/callout.class.js +6 -2
  128. package/dist/components/callout/callout.class.js.map +1 -1
  129. package/dist/components/callout/callout.styles.d.ts.map +1 -1
  130. package/dist/components/callout/callout.styles.js +11 -3
  131. package/dist/components/callout/callout.styles.js.map +1 -1
  132. package/dist/components/carousel/carousel.class.d.ts +9 -1
  133. package/dist/components/carousel/carousel.class.d.ts.map +1 -1
  134. package/dist/components/carousel/carousel.class.js +22 -4
  135. package/dist/components/carousel/carousel.class.js.map +1 -1
  136. package/dist/components/carousel/carousel.styles.d.ts.map +1 -1
  137. package/dist/components/carousel/carousel.styles.js +27 -5
  138. package/dist/components/carousel/carousel.styles.js.map +1 -1
  139. package/dist/components/chart/box-plot.class.d.ts.map +1 -1
  140. package/dist/components/chart/box-plot.class.js +3 -2
  141. package/dist/components/chart/box-plot.class.js.map +1 -1
  142. package/dist/components/chart/chart.class.d.ts +31 -0
  143. package/dist/components/chart/chart.class.d.ts.map +1 -1
  144. package/dist/components/chart/chart.class.js +150 -7
  145. package/dist/components/chart/chart.class.js.map +1 -1
  146. package/dist/components/chart/chart.styles.d.ts.map +1 -1
  147. package/dist/components/chart/chart.styles.js +6 -0
  148. package/dist/components/chart/chart.styles.js.map +1 -1
  149. package/dist/components/chart/lite-chart.class.d.ts +15 -1
  150. package/dist/components/chart/lite-chart.class.d.ts.map +1 -1
  151. package/dist/components/chart/lite-chart.class.js +87 -26
  152. package/dist/components/chart/lite-chart.class.js.map +1 -1
  153. package/dist/components/chart/lite-chart.styles.d.ts.map +1 -1
  154. package/dist/components/chart/lite-chart.styles.js +4 -0
  155. package/dist/components/chart/lite-chart.styles.js.map +1 -1
  156. package/dist/components/chat-composer/chat-composer.class.d.ts +6 -0
  157. package/dist/components/chat-composer/chat-composer.class.d.ts.map +1 -1
  158. package/dist/components/chat-composer/chat-composer.class.js +17 -3
  159. package/dist/components/chat-composer/chat-composer.class.js.map +1 -1
  160. package/dist/components/chat-message/chat-message.class.d.ts +11 -1
  161. package/dist/components/chat-message/chat-message.class.d.ts.map +1 -1
  162. package/dist/components/chat-message/chat-message.class.js +28 -7
  163. package/dist/components/chat-message/chat-message.class.js.map +1 -1
  164. package/dist/components/chat-message/chat-message.styles.d.ts.map +1 -1
  165. package/dist/components/chat-message/chat-message.styles.js +16 -5
  166. package/dist/components/chat-message/chat-message.styles.js.map +1 -1
  167. package/dist/components/chat-viewport/chat-viewport.class.d.ts +143 -0
  168. package/dist/components/chat-viewport/chat-viewport.class.d.ts.map +1 -0
  169. package/dist/components/chat-viewport/chat-viewport.class.js +521 -0
  170. package/dist/components/chat-viewport/chat-viewport.class.js.map +1 -0
  171. package/dist/components/chat-viewport/chat-viewport.d.ts +2 -0
  172. package/dist/components/chat-viewport/chat-viewport.d.ts.map +1 -0
  173. package/dist/components/chat-viewport/chat-viewport.js +5 -0
  174. package/dist/components/chat-viewport/chat-viewport.js.map +1 -0
  175. package/dist/components/chat-viewport/chat-viewport.styles.d.ts +2 -0
  176. package/dist/components/chat-viewport/chat-viewport.styles.d.ts.map +1 -0
  177. package/dist/components/chat-viewport/chat-viewport.styles.js +105 -0
  178. package/dist/components/chat-viewport/chat-viewport.styles.js.map +1 -0
  179. package/dist/components/checkbox/checkbox.class.d.ts +2 -1
  180. package/dist/components/checkbox/checkbox.class.d.ts.map +1 -1
  181. package/dist/components/checkbox/checkbox.class.js +17 -2
  182. package/dist/components/checkbox/checkbox.class.js.map +1 -1
  183. package/dist/components/checkbox-group/checkbox-group.class.d.ts +32 -3
  184. package/dist/components/checkbox-group/checkbox-group.class.d.ts.map +1 -1
  185. package/dist/components/checkbox-group/checkbox-group.class.js +70 -18
  186. package/dist/components/checkbox-group/checkbox-group.class.js.map +1 -1
  187. package/dist/components/checkpoint/checkpoint.class.d.ts +71 -0
  188. package/dist/components/checkpoint/checkpoint.class.d.ts.map +1 -0
  189. package/dist/components/checkpoint/checkpoint.class.js +219 -0
  190. package/dist/components/checkpoint/checkpoint.class.js.map +1 -0
  191. package/dist/components/checkpoint/checkpoint.d.ts +2 -0
  192. package/dist/components/checkpoint/checkpoint.d.ts.map +1 -0
  193. package/dist/components/checkpoint/checkpoint.js +5 -0
  194. package/dist/components/checkpoint/checkpoint.js.map +1 -0
  195. package/dist/components/checkpoint/checkpoint.styles.d.ts +2 -0
  196. package/dist/components/checkpoint/checkpoint.styles.d.ts.map +1 -0
  197. package/dist/components/checkpoint/checkpoint.styles.js +123 -0
  198. package/dist/components/checkpoint/checkpoint.styles.js.map +1 -0
  199. package/dist/components/chip/chip-group.class.d.ts +7 -2
  200. package/dist/components/chip/chip-group.class.d.ts.map +1 -1
  201. package/dist/components/chip/chip-group.class.js +19 -2
  202. package/dist/components/chip/chip-group.class.js.map +1 -1
  203. package/dist/components/chip/chip.styles.d.ts.map +1 -1
  204. package/dist/components/chip/chip.styles.js +12 -3
  205. package/dist/components/chip/chip.styles.js.map +1 -1
  206. package/dist/components/chunk-inspector/chunk-inspector.class.d.ts +131 -0
  207. package/dist/components/chunk-inspector/chunk-inspector.class.d.ts.map +1 -0
  208. package/dist/components/chunk-inspector/chunk-inspector.class.js +170 -0
  209. package/dist/components/chunk-inspector/chunk-inspector.class.js.map +1 -0
  210. package/dist/components/chunk-inspector/chunk-inspector.d.ts +4 -0
  211. package/dist/components/chunk-inspector/chunk-inspector.d.ts.map +1 -0
  212. package/dist/components/chunk-inspector/chunk-inspector.js +7 -0
  213. package/dist/components/chunk-inspector/chunk-inspector.js.map +1 -0
  214. package/dist/components/chunk-inspector/chunk-inspector.styles.d.ts +2 -0
  215. package/dist/components/chunk-inspector/chunk-inspector.styles.d.ts.map +1 -0
  216. package/dist/components/chunk-inspector/chunk-inspector.styles.js +84 -0
  217. package/dist/components/chunk-inspector/chunk-inspector.styles.js.map +1 -0
  218. package/dist/components/citation-badge/citation-badge.class.d.ts +7 -2
  219. package/dist/components/citation-badge/citation-badge.class.d.ts.map +1 -1
  220. package/dist/components/citation-badge/citation-badge.class.js +15 -3
  221. package/dist/components/citation-badge/citation-badge.class.js.map +1 -1
  222. package/dist/components/code-block/code-block-core.class.d.ts +62 -0
  223. package/dist/components/code-block/code-block-core.class.d.ts.map +1 -1
  224. package/dist/components/code-block/code-block-core.class.js +229 -42
  225. package/dist/components/code-block/code-block-core.class.js.map +1 -1
  226. package/dist/components/code-block/code-block-shared.d.ts +29 -5
  227. package/dist/components/code-block/code-block-shared.d.ts.map +1 -1
  228. package/dist/components/code-block/code-block-shared.js +73 -5
  229. package/dist/components/code-block/code-block-shared.js.map +1 -1
  230. package/dist/components/code-block/code-block.class.d.ts +62 -0
  231. package/dist/components/code-block/code-block.class.d.ts.map +1 -1
  232. package/dist/components/code-block/code-block.class.js +229 -42
  233. package/dist/components/code-block/code-block.class.js.map +1 -1
  234. package/dist/components/code-block/code-block.styles.d.ts.map +1 -1
  235. package/dist/components/code-block/code-block.styles.js +41 -0
  236. package/dist/components/code-block/code-block.styles.js.map +1 -1
  237. package/dist/components/code-editor/code-editor.class.d.ts +17 -1
  238. package/dist/components/code-editor/code-editor.class.d.ts.map +1 -1
  239. package/dist/components/code-editor/code-editor.class.js +50 -11
  240. package/dist/components/code-editor/code-editor.class.js.map +1 -1
  241. package/dist/components/combobox/combobox.class.d.ts +21 -2
  242. package/dist/components/combobox/combobox.class.d.ts.map +1 -1
  243. package/dist/components/combobox/combobox.class.js +41 -12
  244. package/dist/components/combobox/combobox.class.js.map +1 -1
  245. package/dist/components/combobox/combobox.styles.d.ts.map +1 -1
  246. package/dist/components/combobox/combobox.styles.js +29 -7
  247. package/dist/components/combobox/combobox.styles.js.map +1 -1
  248. package/dist/components/command-palette/command-palette.class.d.ts +14 -0
  249. package/dist/components/command-palette/command-palette.class.d.ts.map +1 -1
  250. package/dist/components/command-palette/command-palette.class.js +33 -6
  251. package/dist/components/command-palette/command-palette.class.js.map +1 -1
  252. package/dist/components/commit-card/commit-card.class.d.ts +78 -0
  253. package/dist/components/commit-card/commit-card.class.d.ts.map +1 -0
  254. package/dist/components/commit-card/commit-card.class.js +209 -0
  255. package/dist/components/commit-card/commit-card.class.js.map +1 -0
  256. package/dist/components/commit-card/commit-card.d.ts +2 -0
  257. package/dist/components/commit-card/commit-card.d.ts.map +1 -0
  258. package/dist/components/commit-card/commit-card.js +5 -0
  259. package/dist/components/commit-card/commit-card.js.map +1 -0
  260. package/dist/components/commit-card/commit-card.styles.d.ts +2 -0
  261. package/dist/components/commit-card/commit-card.styles.d.ts.map +1 -0
  262. package/dist/components/commit-card/commit-card.styles.js +69 -0
  263. package/dist/components/commit-card/commit-card.styles.js.map +1 -0
  264. package/dist/components/community-card/community-card.class.d.ts +68 -0
  265. package/dist/components/community-card/community-card.class.d.ts.map +1 -0
  266. package/dist/components/community-card/community-card.class.js +109 -0
  267. package/dist/components/community-card/community-card.class.js.map +1 -0
  268. package/dist/components/community-card/community-card.d.ts +5 -0
  269. package/dist/components/community-card/community-card.d.ts.map +1 -0
  270. package/dist/components/community-card/community-card.js +8 -0
  271. package/dist/components/community-card/community-card.js.map +1 -0
  272. package/dist/components/community-card/community-card.styles.d.ts +2 -0
  273. package/dist/components/community-card/community-card.styles.d.ts.map +1 -0
  274. package/dist/components/community-card/community-card.styles.js +74 -0
  275. package/dist/components/community-card/community-card.styles.js.map +1 -0
  276. package/dist/components/compare-panel/compare-panel.class.d.ts +112 -0
  277. package/dist/components/compare-panel/compare-panel.class.d.ts.map +1 -0
  278. package/dist/components/compare-panel/compare-panel.class.js +260 -0
  279. package/dist/components/compare-panel/compare-panel.class.js.map +1 -0
  280. package/dist/components/compare-panel/compare-panel.d.ts +3 -0
  281. package/dist/components/compare-panel/compare-panel.d.ts.map +1 -0
  282. package/dist/components/compare-panel/compare-panel.js +6 -0
  283. package/dist/components/compare-panel/compare-panel.js.map +1 -0
  284. package/dist/components/compare-panel/compare-panel.styles.d.ts +2 -0
  285. package/dist/components/compare-panel/compare-panel.styles.d.ts.map +1 -0
  286. package/dist/components/compare-panel/compare-panel.styles.js +97 -0
  287. package/dist/components/compare-panel/compare-panel.styles.js.map +1 -0
  288. package/dist/components/confirm-bar/confirm-bar.class.d.ts +81 -0
  289. package/dist/components/confirm-bar/confirm-bar.class.d.ts.map +1 -0
  290. package/dist/components/confirm-bar/confirm-bar.class.js +193 -0
  291. package/dist/components/confirm-bar/confirm-bar.class.js.map +1 -0
  292. package/dist/components/confirm-bar/confirm-bar.d.ts +5 -0
  293. package/dist/components/confirm-bar/confirm-bar.d.ts.map +1 -0
  294. package/dist/components/confirm-bar/confirm-bar.js +8 -0
  295. package/dist/components/confirm-bar/confirm-bar.js.map +1 -0
  296. package/dist/components/confirm-bar/confirm-bar.styles.d.ts +2 -0
  297. package/dist/components/confirm-bar/confirm-bar.styles.d.ts.map +1 -0
  298. package/dist/components/confirm-bar/confirm-bar.styles.js +96 -0
  299. package/dist/components/confirm-bar/confirm-bar.styles.js.map +1 -0
  300. package/dist/components/context-meter/context-meter.class.d.ts +8 -1
  301. package/dist/components/context-meter/context-meter.class.d.ts.map +1 -1
  302. package/dist/components/context-meter/context-meter.class.js +25 -4
  303. package/dist/components/context-meter/context-meter.class.js.map +1 -1
  304. package/dist/components/context-meter/context-meter.styles.d.ts.map +1 -1
  305. package/dist/components/context-meter/context-meter.styles.js +6 -0
  306. package/dist/components/context-meter/context-meter.styles.js.map +1 -1
  307. package/dist/components/conversation-item/conversation-item.class.d.ts +17 -1
  308. package/dist/components/conversation-item/conversation-item.class.d.ts.map +1 -1
  309. package/dist/components/conversation-item/conversation-item.class.js +43 -4
  310. package/dist/components/conversation-item/conversation-item.class.js.map +1 -1
  311. package/dist/components/conversation-item/conversation-item.styles.d.ts.map +1 -1
  312. package/dist/components/conversation-item/conversation-item.styles.js +15 -2
  313. package/dist/components/conversation-item/conversation-item.styles.js.map +1 -1
  314. package/dist/components/copy-button/copy-button.class.d.ts.map +1 -1
  315. package/dist/components/copy-button/copy-button.class.js +4 -3
  316. package/dist/components/copy-button/copy-button.class.js.map +1 -1
  317. package/dist/components/csv-viewer/csv-viewer.class.d.ts +83 -3
  318. package/dist/components/csv-viewer/csv-viewer.class.d.ts.map +1 -1
  319. package/dist/components/csv-viewer/csv-viewer.class.js +204 -6
  320. package/dist/components/csv-viewer/csv-viewer.class.js.map +1 -1
  321. package/dist/components/csv-viewer/csv-viewer.js +10 -1
  322. package/dist/components/csv-viewer/csv-viewer.js.map +1 -1
  323. package/dist/components/data-grid/data-grid.class.d.ts +2 -1
  324. package/dist/components/data-grid/data-grid.class.d.ts.map +1 -1
  325. package/dist/components/data-grid/data-grid.class.js +10 -1
  326. package/dist/components/data-grid/data-grid.class.js.map +1 -1
  327. package/dist/components/dataset-viewer/dataset-viewer.class.d.ts +93 -4
  328. package/dist/components/dataset-viewer/dataset-viewer.class.d.ts.map +1 -1
  329. package/dist/components/dataset-viewer/dataset-viewer.class.js +212 -14
  330. package/dist/components/dataset-viewer/dataset-viewer.class.js.map +1 -1
  331. package/dist/components/dataset-viewer/dataset-viewer.js +11 -6
  332. package/dist/components/dataset-viewer/dataset-viewer.js.map +1 -1
  333. package/dist/components/dataset-viewer/dataset-viewer.styles.d.ts.map +1 -1
  334. package/dist/components/dataset-viewer/dataset-viewer.styles.js +52 -5
  335. package/dist/components/dataset-viewer/dataset-viewer.styles.js.map +1 -1
  336. package/dist/components/date-picker/calendar-core.d.ts.map +1 -1
  337. package/dist/components/date-picker/calendar-core.js +3 -2
  338. package/dist/components/date-picker/calendar-core.js.map +1 -1
  339. package/dist/components/date-picker/date-input.class.d.ts +6 -0
  340. package/dist/components/date-picker/date-input.class.d.ts.map +1 -1
  341. package/dist/components/date-picker/date-input.class.js +13 -3
  342. package/dist/components/date-picker/date-input.class.js.map +1 -1
  343. package/dist/components/date-picker/date-picker.class.d.ts.map +1 -1
  344. package/dist/components/date-picker/date-picker.class.js +31 -7
  345. package/dist/components/date-picker/date-picker.class.js.map +1 -1
  346. package/dist/components/date-picker/date-picker.styles.d.ts.map +1 -1
  347. package/dist/components/date-picker/date-picker.styles.js +5 -0
  348. package/dist/components/date-picker/date-picker.styles.js.map +1 -1
  349. package/dist/components/details/accordion-item.class.d.ts +4 -1
  350. package/dist/components/details/accordion-item.class.d.ts.map +1 -1
  351. package/dist/components/details/accordion-item.class.js +4 -1
  352. package/dist/components/details/accordion-item.class.js.map +1 -1
  353. package/dist/components/diff-view/diff-line-diff.d.ts +13 -0
  354. package/dist/components/diff-view/diff-line-diff.d.ts.map +1 -1
  355. package/dist/components/diff-view/diff-line-diff.js +33 -0
  356. package/dist/components/diff-view/diff-line-diff.js.map +1 -1
  357. package/dist/components/diff-view/diff-view.class.d.ts +27 -1
  358. package/dist/components/diff-view/diff-view.class.d.ts.map +1 -1
  359. package/dist/components/diff-view/diff-view.class.js +130 -4
  360. package/dist/components/diff-view/diff-view.class.js.map +1 -1
  361. package/dist/components/diff-view/diff-view.styles.d.ts.map +1 -1
  362. package/dist/components/diff-view/diff-view.styles.js +18 -2
  363. package/dist/components/diff-view/diff-view.styles.js.map +1 -1
  364. package/dist/components/dock-panel/dock-panel.class.d.ts.map +1 -1
  365. package/dist/components/dock-panel/dock-panel.class.js +5 -0
  366. package/dist/components/dock-panel/dock-panel.class.js.map +1 -1
  367. package/dist/components/dock-panel/dock-panel.styles.d.ts.map +1 -1
  368. package/dist/components/dock-panel/dock-panel.styles.js +8 -0
  369. package/dist/components/dock-panel/dock-panel.styles.js.map +1 -1
  370. package/dist/components/document-preview/document-preview.class.d.ts +32 -0
  371. package/dist/components/document-preview/document-preview.class.d.ts.map +1 -1
  372. package/dist/components/document-preview/document-preview.class.js +93 -5
  373. package/dist/components/document-preview/document-preview.class.js.map +1 -1
  374. package/dist/components/document-preview/document-preview.styles.d.ts.map +1 -1
  375. package/dist/components/document-preview/document-preview.styles.js +18 -0
  376. package/dist/components/document-preview/document-preview.styles.js.map +1 -1
  377. package/dist/components/document-viewer/anchors.d.ts +89 -0
  378. package/dist/components/document-viewer/anchors.d.ts.map +1 -0
  379. package/dist/components/document-viewer/anchors.js +4 -0
  380. package/dist/components/document-viewer/anchors.js.map +1 -0
  381. package/dist/components/document-viewer/document-viewer.class.d.ts +23 -0
  382. package/dist/components/document-viewer/document-viewer.class.d.ts.map +1 -1
  383. package/dist/components/document-viewer/document-viewer.class.js +72 -3
  384. package/dist/components/document-viewer/document-viewer.class.js.map +1 -1
  385. package/dist/components/document-viewer/registry.d.ts +8 -0
  386. package/dist/components/document-viewer/registry.d.ts.map +1 -1
  387. package/dist/components/document-viewer/registry.js.map +1 -1
  388. package/dist/components/docx-viewer/docx-viewer.class.d.ts +128 -2
  389. package/dist/components/docx-viewer/docx-viewer.class.d.ts.map +1 -1
  390. package/dist/components/docx-viewer/docx-viewer.class.js +433 -3
  391. package/dist/components/docx-viewer/docx-viewer.class.js.map +1 -1
  392. package/dist/components/docx-viewer/docx-viewer.js +1 -0
  393. package/dist/components/docx-viewer/docx-viewer.js.map +1 -1
  394. package/dist/components/docx-viewer/docx-viewer.styles.d.ts.map +1 -1
  395. package/dist/components/docx-viewer/docx-viewer.styles.js +56 -0
  396. package/dist/components/docx-viewer/docx-viewer.styles.js.map +1 -1
  397. package/dist/components/ebook-viewer/ebook-viewer-register.js +1 -0
  398. package/dist/components/ebook-viewer/ebook-viewer-register.js.map +1 -1
  399. package/dist/components/ebook-viewer/ebook-viewer.class.d.ts +111 -2
  400. package/dist/components/ebook-viewer/ebook-viewer.class.d.ts.map +1 -1
  401. package/dist/components/ebook-viewer/ebook-viewer.class.js +289 -4
  402. package/dist/components/ebook-viewer/ebook-viewer.class.js.map +1 -1
  403. package/dist/components/ebook-viewer/ebook-viewer.styles.d.ts.map +1 -1
  404. package/dist/components/ebook-viewer/ebook-viewer.styles.js +6 -2
  405. package/dist/components/ebook-viewer/ebook-viewer.styles.js.map +1 -1
  406. package/dist/components/email-viewer/email-viewer.class.d.ts +26 -1
  407. package/dist/components/email-viewer/email-viewer.class.d.ts.map +1 -1
  408. package/dist/components/email-viewer/email-viewer.class.js +110 -3
  409. package/dist/components/email-viewer/email-viewer.class.js.map +1 -1
  410. package/dist/components/email-viewer/email-viewer.js +1 -0
  411. package/dist/components/email-viewer/email-viewer.js.map +1 -1
  412. package/dist/components/email-viewer/email-viewer.styles.d.ts.map +1 -1
  413. package/dist/components/email-viewer/email-viewer.styles.js +31 -1
  414. package/dist/components/email-viewer/email-viewer.styles.js.map +1 -1
  415. package/dist/components/emoji-picker/emoji-data-loader.d.ts +14 -0
  416. package/dist/components/emoji-picker/emoji-data-loader.d.ts.map +1 -0
  417. package/dist/components/emoji-picker/emoji-data-loader.js +78 -0
  418. package/dist/components/emoji-picker/emoji-data-loader.js.map +1 -0
  419. package/dist/components/emoji-picker/emoji-picker.class.d.ts +98 -0
  420. package/dist/components/emoji-picker/emoji-picker.class.d.ts.map +1 -0
  421. package/dist/components/emoji-picker/emoji-picker.class.js +285 -0
  422. package/dist/components/emoji-picker/emoji-picker.class.js.map +1 -0
  423. package/dist/components/emoji-picker/emoji-picker.d.ts +2 -0
  424. package/dist/components/emoji-picker/emoji-picker.d.ts.map +1 -0
  425. package/dist/components/emoji-picker/emoji-picker.js +5 -0
  426. package/dist/components/emoji-picker/emoji-picker.js.map +1 -0
  427. package/dist/components/emoji-picker/emoji-picker.styles.d.ts +2 -0
  428. package/dist/components/emoji-picker/emoji-picker.styles.d.ts.map +1 -0
  429. package/dist/components/emoji-picker/emoji-picker.styles.js +70 -0
  430. package/dist/components/emoji-picker/emoji-picker.styles.js.map +1 -0
  431. package/dist/components/entity-card/entity-card.class.d.ts +81 -0
  432. package/dist/components/entity-card/entity-card.class.d.ts.map +1 -0
  433. package/dist/components/entity-card/entity-card.class.js +148 -0
  434. package/dist/components/entity-card/entity-card.class.js.map +1 -0
  435. package/dist/components/entity-card/entity-card.d.ts +7 -0
  436. package/dist/components/entity-card/entity-card.d.ts.map +1 -0
  437. package/dist/components/entity-card/entity-card.js +10 -0
  438. package/dist/components/entity-card/entity-card.js.map +1 -0
  439. package/dist/components/entity-card/entity-card.styles.d.ts +2 -0
  440. package/dist/components/entity-card/entity-card.styles.d.ts.map +1 -0
  441. package/dist/components/entity-card/entity-card.styles.js +48 -0
  442. package/dist/components/entity-card/entity-card.styles.js.map +1 -0
  443. package/dist/components/entity-chip/entity-chip.class.d.ts +72 -0
  444. package/dist/components/entity-chip/entity-chip.class.d.ts.map +1 -0
  445. package/dist/components/entity-chip/entity-chip.class.js +200 -0
  446. package/dist/components/entity-chip/entity-chip.class.js.map +1 -0
  447. package/dist/components/entity-chip/entity-chip.d.ts +2 -0
  448. package/dist/components/entity-chip/entity-chip.d.ts.map +1 -0
  449. package/dist/components/entity-chip/entity-chip.js +5 -0
  450. package/dist/components/entity-chip/entity-chip.js.map +1 -0
  451. package/dist/components/entity-chip/entity-chip.styles.d.ts +2 -0
  452. package/dist/components/entity-chip/entity-chip.styles.d.ts.map +1 -0
  453. package/dist/components/entity-chip/entity-chip.styles.js +46 -0
  454. package/dist/components/entity-chip/entity-chip.styles.js.map +1 -0
  455. package/dist/components/env-list/env-list.class.d.ts +55 -0
  456. package/dist/components/env-list/env-list.class.d.ts.map +1 -0
  457. package/dist/components/env-list/env-list.class.js +143 -0
  458. package/dist/components/env-list/env-list.class.js.map +1 -0
  459. package/dist/components/env-list/env-list.d.ts +2 -0
  460. package/dist/components/env-list/env-list.d.ts.map +1 -0
  461. package/dist/components/env-list/env-list.js +5 -0
  462. package/dist/components/env-list/env-list.js.map +1 -0
  463. package/dist/components/env-list/env-list.styles.d.ts +2 -0
  464. package/dist/components/env-list/env-list.styles.d.ts.map +1 -0
  465. package/dist/components/env-list/env-list.styles.js +44 -0
  466. package/dist/components/env-list/env-list.styles.js.map +1 -0
  467. package/dist/components/file-icon/file-icon.class.d.ts.map +1 -1
  468. package/dist/components/file-icon/file-icon.class.js +6 -1
  469. package/dist/components/file-icon/file-icon.class.js.map +1 -1
  470. package/dist/components/file-input/file-input.class.d.ts +19 -0
  471. package/dist/components/file-input/file-input.class.d.ts.map +1 -1
  472. package/dist/components/file-input/file-input.class.js +27 -1
  473. package/dist/components/file-input/file-input.class.js.map +1 -1
  474. package/dist/components/file-tree/file-tree.class.d.ts +68 -0
  475. package/dist/components/file-tree/file-tree.class.d.ts.map +1 -0
  476. package/dist/components/file-tree/file-tree.class.js +235 -0
  477. package/dist/components/file-tree/file-tree.class.js.map +1 -0
  478. package/dist/components/file-tree/file-tree.d.ts +2 -0
  479. package/dist/components/file-tree/file-tree.d.ts.map +1 -0
  480. package/dist/components/file-tree/file-tree.js +5 -0
  481. package/dist/components/file-tree/file-tree.js.map +1 -0
  482. package/dist/components/file-tree/file-tree.styles.d.ts +2 -0
  483. package/dist/components/file-tree/file-tree.styles.d.ts.map +1 -0
  484. package/dist/components/file-tree/file-tree.styles.js +10 -0
  485. package/dist/components/file-tree/file-tree.styles.js.map +1 -0
  486. package/dist/components/flag/flag.class.d.ts.map +1 -1
  487. package/dist/components/flag/flag.class.js +7 -15
  488. package/dist/components/flag/flag.class.js.map +1 -1
  489. package/dist/components/flow-canvas/flow-canvas.class.d.ts +411 -0
  490. package/dist/components/flow-canvas/flow-canvas.class.d.ts.map +1 -0
  491. package/dist/components/flow-canvas/flow-canvas.class.js +1570 -0
  492. package/dist/components/flow-canvas/flow-canvas.class.js.map +1 -0
  493. package/dist/components/flow-canvas/flow-canvas.d.ts +4 -0
  494. package/dist/components/flow-canvas/flow-canvas.d.ts.map +1 -0
  495. package/dist/components/flow-canvas/flow-canvas.js +7 -0
  496. package/dist/components/flow-canvas/flow-canvas.js.map +1 -0
  497. package/dist/components/flow-canvas/flow-canvas.styles.d.ts +2 -0
  498. package/dist/components/flow-canvas/flow-canvas.styles.d.ts.map +1 -0
  499. package/dist/components/flow-canvas/flow-canvas.styles.js +186 -0
  500. package/dist/components/flow-canvas/flow-canvas.styles.js.map +1 -0
  501. package/dist/components/flow-controls/flow-controls.class.d.ts +44 -0
  502. package/dist/components/flow-controls/flow-controls.class.d.ts.map +1 -0
  503. package/dist/components/flow-controls/flow-controls.class.js +203 -0
  504. package/dist/components/flow-controls/flow-controls.class.js.map +1 -0
  505. package/dist/components/flow-controls/flow-controls.d.ts +2 -0
  506. package/dist/components/flow-controls/flow-controls.d.ts.map +1 -0
  507. package/dist/components/flow-controls/flow-controls.js +5 -0
  508. package/dist/components/flow-controls/flow-controls.js.map +1 -0
  509. package/dist/components/flow-controls/flow-controls.styles.d.ts +2 -0
  510. package/dist/components/flow-controls/flow-controls.styles.d.ts.map +1 -0
  511. package/dist/components/flow-controls/flow-controls.styles.js +55 -0
  512. package/dist/components/flow-controls/flow-controls.styles.js.map +1 -0
  513. package/dist/components/flow-minimap/flow-minimap.class.d.ts +62 -0
  514. package/dist/components/flow-minimap/flow-minimap.class.d.ts.map +1 -0
  515. package/dist/components/flow-minimap/flow-minimap.class.js +291 -0
  516. package/dist/components/flow-minimap/flow-minimap.class.js.map +1 -0
  517. package/dist/components/flow-minimap/flow-minimap.d.ts +2 -0
  518. package/dist/components/flow-minimap/flow-minimap.d.ts.map +1 -0
  519. package/dist/components/flow-minimap/flow-minimap.js +5 -0
  520. package/dist/components/flow-minimap/flow-minimap.js.map +1 -0
  521. package/dist/components/flow-minimap/flow-minimap.styles.d.ts +2 -0
  522. package/dist/components/flow-minimap/flow-minimap.styles.d.ts.map +1 -0
  523. package/dist/components/flow-minimap/flow-minimap.styles.js +48 -0
  524. package/dist/components/flow-minimap/flow-minimap.styles.js.map +1 -0
  525. package/dist/components/flow-node/flow-node.class.d.ts +70 -0
  526. package/dist/components/flow-node/flow-node.class.d.ts.map +1 -0
  527. package/dist/components/flow-node/flow-node.class.js +187 -0
  528. package/dist/components/flow-node/flow-node.class.js.map +1 -0
  529. package/dist/components/flow-node/flow-node.d.ts +2 -0
  530. package/dist/components/flow-node/flow-node.d.ts.map +1 -0
  531. package/dist/components/flow-node/flow-node.js +5 -0
  532. package/dist/components/flow-node/flow-node.js.map +1 -0
  533. package/dist/components/flow-node/flow-node.styles.d.ts +2 -0
  534. package/dist/components/flow-node/flow-node.styles.d.ts.map +1 -0
  535. package/dist/components/flow-node/flow-node.styles.js +127 -0
  536. package/dist/components/flow-node/flow-node.styles.js.map +1 -0
  537. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts +46 -0
  538. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts.map +1 -0
  539. package/dist/components/flow-run-overlay/flow-run-overlay.class.js +182 -0
  540. package/dist/components/flow-run-overlay/flow-run-overlay.class.js.map +1 -0
  541. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts +2 -0
  542. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts.map +1 -0
  543. package/dist/components/flow-run-overlay/flow-run-overlay.js +5 -0
  544. package/dist/components/flow-run-overlay/flow-run-overlay.js.map +1 -0
  545. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts +2 -0
  546. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts.map +1 -0
  547. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js +38 -0
  548. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js.map +1 -0
  549. package/dist/components/format/format-bytes.class.d.ts +8 -0
  550. package/dist/components/format/format-bytes.class.d.ts.map +1 -1
  551. package/dist/components/format/format-bytes.class.js +36 -7
  552. package/dist/components/format/format-bytes.class.js.map +1 -1
  553. package/dist/components/format/format-date.class.d.ts.map +1 -1
  554. package/dist/components/format/format-date.class.js +2 -1
  555. package/dist/components/format/format-date.class.js.map +1 -1
  556. package/dist/components/format/format-number.class.d.ts +6 -0
  557. package/dist/components/format/format-number.class.d.ts.map +1 -1
  558. package/dist/components/format/format-number.class.js +34 -5
  559. package/dist/components/format/format-number.class.js.map +1 -1
  560. package/dist/components/format/relative-time.class.d.ts.map +1 -1
  561. package/dist/components/format/relative-time.class.js +2 -1
  562. package/dist/components/format/relative-time.class.js.map +1 -1
  563. package/dist/components/generation-status/generation-status.class.d.ts +3 -0
  564. package/dist/components/generation-status/generation-status.class.d.ts.map +1 -1
  565. package/dist/components/generation-status/generation-status.class.js +28 -11
  566. package/dist/components/generation-status/generation-status.class.js.map +1 -1
  567. package/dist/components/generation-status/generation-status.styles.d.ts.map +1 -1
  568. package/dist/components/generation-status/generation-status.styles.js +7 -4
  569. package/dist/components/generation-status/generation-status.styles.js.map +1 -1
  570. package/dist/components/geojson-view/geojson-view.class.d.ts +40 -0
  571. package/dist/components/geojson-view/geojson-view.class.d.ts.map +1 -0
  572. package/dist/components/geojson-view/geojson-view.class.js +185 -0
  573. package/dist/components/geojson-view/geojson-view.class.js.map +1 -0
  574. package/dist/components/geojson-view/geojson-view.d.ts +5 -0
  575. package/dist/components/geojson-view/geojson-view.d.ts.map +1 -0
  576. package/dist/components/geojson-view/geojson-view.js +18 -0
  577. package/dist/components/geojson-view/geojson-view.js.map +1 -0
  578. package/dist/components/graph/graph-canvas.d.ts +113 -0
  579. package/dist/components/graph/graph-canvas.d.ts.map +1 -0
  580. package/dist/components/graph/graph-canvas.js +180 -0
  581. package/dist/components/graph/graph-canvas.js.map +1 -0
  582. package/dist/components/graph/graph-hull.d.ts +28 -0
  583. package/dist/components/graph/graph-hull.d.ts.map +1 -0
  584. package/dist/components/graph/graph-hull.js +70 -0
  585. package/dist/components/graph/graph-hull.js.map +1 -0
  586. package/dist/components/graph/graph-loader.d.ts +6 -0
  587. package/dist/components/graph/graph-loader.d.ts.map +1 -1
  588. package/dist/components/graph/graph-loader.js +2 -0
  589. package/dist/components/graph/graph-loader.js.map +1 -1
  590. package/dist/components/graph/graph.class.d.ts +461 -2
  591. package/dist/components/graph/graph.class.d.ts.map +1 -1
  592. package/dist/components/graph/graph.class.js +1728 -121
  593. package/dist/components/graph/graph.class.js.map +1 -1
  594. package/dist/components/graph/graph.styles.d.ts.map +1 -1
  595. package/dist/components/graph/graph.styles.js +106 -0
  596. package/dist/components/graph/graph.styles.js.map +1 -1
  597. package/dist/components/graph-legend/graph-legend.class.d.ts +62 -0
  598. package/dist/components/graph-legend/graph-legend.class.d.ts.map +1 -0
  599. package/dist/components/graph-legend/graph-legend.class.js +132 -0
  600. package/dist/components/graph-legend/graph-legend.class.js.map +1 -0
  601. package/dist/components/graph-legend/graph-legend.d.ts +2 -0
  602. package/dist/components/graph-legend/graph-legend.d.ts.map +1 -0
  603. package/dist/components/graph-legend/graph-legend.js +5 -0
  604. package/dist/components/graph-legend/graph-legend.js.map +1 -0
  605. package/dist/components/graph-legend/graph-legend.styles.d.ts +2 -0
  606. package/dist/components/graph-legend/graph-legend.styles.d.ts.map +1 -0
  607. package/dist/components/graph-legend/graph-legend.styles.js +59 -0
  608. package/dist/components/graph-legend/graph-legend.styles.js.map +1 -0
  609. package/dist/components/handoff-divider/handoff-divider.class.d.ts +46 -0
  610. package/dist/components/handoff-divider/handoff-divider.class.d.ts.map +1 -0
  611. package/dist/components/handoff-divider/handoff-divider.class.js +99 -0
  612. package/dist/components/handoff-divider/handoff-divider.class.js.map +1 -0
  613. package/dist/components/handoff-divider/handoff-divider.d.ts +2 -0
  614. package/dist/components/handoff-divider/handoff-divider.d.ts.map +1 -0
  615. package/dist/components/handoff-divider/handoff-divider.js +5 -0
  616. package/dist/components/handoff-divider/handoff-divider.js.map +1 -0
  617. package/dist/components/handoff-divider/handoff-divider.styles.d.ts +2 -0
  618. package/dist/components/handoff-divider/handoff-divider.styles.d.ts.map +1 -0
  619. package/dist/components/handoff-divider/handoff-divider.styles.js +48 -0
  620. package/dist/components/handoff-divider/handoff-divider.styles.js.map +1 -0
  621. package/dist/components/heatmap/heatmap.class.d.ts +12 -3
  622. package/dist/components/heatmap/heatmap.class.d.ts.map +1 -1
  623. package/dist/components/heatmap/heatmap.class.js +88 -50
  624. package/dist/components/heatmap/heatmap.class.js.map +1 -1
  625. package/dist/components/highlight-layer/highlight-layer.class.d.ts +60 -0
  626. package/dist/components/highlight-layer/highlight-layer.class.d.ts.map +1 -0
  627. package/dist/components/highlight-layer/highlight-layer.class.js +151 -0
  628. package/dist/components/highlight-layer/highlight-layer.class.js.map +1 -0
  629. package/dist/components/highlight-layer/highlight-layer.d.ts +2 -0
  630. package/dist/components/highlight-layer/highlight-layer.d.ts.map +1 -0
  631. package/dist/components/highlight-layer/highlight-layer.js +5 -0
  632. package/dist/components/highlight-layer/highlight-layer.js.map +1 -0
  633. package/dist/components/highlight-layer/highlight-layer.styles.d.ts +2 -0
  634. package/dist/components/highlight-layer/highlight-layer.styles.d.ts.map +1 -0
  635. package/dist/components/highlight-layer/highlight-layer.styles.js +68 -0
  636. package/dist/components/highlight-layer/highlight-layer.styles.js.map +1 -0
  637. package/dist/components/image-comparer/image-comparer.class.d.ts.map +1 -1
  638. package/dist/components/image-comparer/image-comparer.class.js +2 -1
  639. package/dist/components/image-comparer/image-comparer.class.js.map +1 -1
  640. package/dist/components/image-viewer/image-viewer.class.d.ts +143 -0
  641. package/dist/components/image-viewer/image-viewer.class.d.ts.map +1 -0
  642. package/dist/components/image-viewer/image-viewer.class.js +389 -0
  643. package/dist/components/image-viewer/image-viewer.class.js.map +1 -0
  644. package/dist/components/image-viewer/image-viewer.d.ts +4 -0
  645. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  646. package/dist/components/image-viewer/image-viewer.js +25 -0
  647. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  648. package/dist/components/image-viewer/image-viewer.styles.d.ts +2 -0
  649. package/dist/components/image-viewer/image-viewer.styles.d.ts.map +1 -0
  650. package/dist/components/image-viewer/image-viewer.styles.js +126 -0
  651. package/dist/components/image-viewer/image-viewer.styles.js.map +1 -0
  652. package/dist/components/input/input.class.d.ts +6 -3
  653. package/dist/components/input/input.class.d.ts.map +1 -1
  654. package/dist/components/input/input.class.js +4 -1
  655. package/dist/components/input/input.class.js.map +1 -1
  656. package/dist/components/input/input.styles.d.ts.map +1 -1
  657. package/dist/components/input/input.styles.js +5 -0
  658. package/dist/components/input/input.styles.js.map +1 -1
  659. package/dist/components/intersection-observer/intersection-observer.class.d.ts +1 -0
  660. package/dist/components/intersection-observer/intersection-observer.class.d.ts.map +1 -1
  661. package/dist/components/intersection-observer/intersection-observer.class.js +15 -0
  662. package/dist/components/intersection-observer/intersection-observer.class.js.map +1 -1
  663. package/dist/components/json-viewer/json-viewer.class.d.ts +39 -2
  664. package/dist/components/json-viewer/json-viewer.class.d.ts.map +1 -1
  665. package/dist/components/json-viewer/json-viewer.class.js +95 -6
  666. package/dist/components/json-viewer/json-viewer.class.js.map +1 -1
  667. package/dist/components/known-date/known-date.class.d.ts.map +1 -1
  668. package/dist/components/known-date/known-date.class.js +2 -1
  669. package/dist/components/known-date/known-date.class.js.map +1 -1
  670. package/dist/components/lightbox/lightbox.class.d.ts +2 -2
  671. package/dist/components/lightbox/lightbox.class.d.ts.map +1 -1
  672. package/dist/components/lightbox/lightbox.class.js +16 -7
  673. package/dist/components/lightbox/lightbox.class.js.map +1 -1
  674. package/dist/components/live-region/live-region.class.d.ts +5 -0
  675. package/dist/components/live-region/live-region.class.d.ts.map +1 -1
  676. package/dist/components/live-region/live-region.class.js +10 -2
  677. package/dist/components/live-region/live-region.class.js.map +1 -1
  678. package/dist/components/map/map.class.d.ts +33 -3
  679. package/dist/components/map/map.class.d.ts.map +1 -1
  680. package/dist/components/map/map.class.js +130 -5
  681. package/dist/components/map/map.class.js.map +1 -1
  682. package/dist/components/markdown/katex-loader.d.ts +23 -0
  683. package/dist/components/markdown/katex-loader.d.ts.map +1 -0
  684. package/dist/components/markdown/katex-loader.js +33 -0
  685. package/dist/components/markdown/katex-loader.js.map +1 -0
  686. package/dist/components/markdown/markdown-core.class.d.ts +334 -0
  687. package/dist/components/markdown/markdown-core.class.d.ts.map +1 -0
  688. package/dist/components/markdown/markdown-core.class.js +999 -0
  689. package/dist/components/markdown/markdown-core.class.js.map +1 -0
  690. package/dist/components/markdown/markdown-core.d.ts +2 -0
  691. package/dist/components/markdown/markdown-core.d.ts.map +1 -0
  692. package/dist/components/markdown/markdown-core.js +5 -0
  693. package/dist/components/markdown/markdown-core.js.map +1 -0
  694. package/dist/components/markdown/markdown.class.d.ts +191 -4
  695. package/dist/components/markdown/markdown.class.d.ts.map +1 -1
  696. package/dist/components/markdown/markdown.class.js +584 -11
  697. package/dist/components/markdown/markdown.class.js.map +1 -1
  698. package/dist/components/markdown/markdown.styles.d.ts.map +1 -1
  699. package/dist/components/markdown/markdown.styles.js +53 -0
  700. package/dist/components/markdown/markdown.styles.js.map +1 -1
  701. package/dist/components/media-card/media-card.styles.d.ts.map +1 -1
  702. package/dist/components/media-card/media-card.styles.js +6 -2
  703. package/dist/components/media-card/media-card.styles.js.map +1 -1
  704. package/dist/components/mention-popover/mention-popover.styles.d.ts.map +1 -1
  705. package/dist/components/mention-popover/mention-popover.styles.js +6 -3
  706. package/dist/components/mention-popover/mention-popover.styles.js.map +1 -1
  707. package/dist/components/message-actions/message-actions.class.d.ts +112 -0
  708. package/dist/components/message-actions/message-actions.class.d.ts.map +1 -0
  709. package/dist/components/message-actions/message-actions.class.js +277 -0
  710. package/dist/components/message-actions/message-actions.class.js.map +1 -0
  711. package/dist/components/message-actions/message-actions.d.ts +4 -0
  712. package/dist/components/message-actions/message-actions.d.ts.map +1 -0
  713. package/dist/components/message-actions/message-actions.js +7 -0
  714. package/dist/components/message-actions/message-actions.js.map +1 -0
  715. package/dist/components/message-actions/message-actions.styles.d.ts +2 -0
  716. package/dist/components/message-actions/message-actions.styles.d.ts.map +1 -0
  717. package/dist/components/message-actions/message-actions.styles.js +66 -0
  718. package/dist/components/message-actions/message-actions.styles.js.map +1 -0
  719. package/dist/components/message-feedback/message-feedback.class.d.ts +91 -0
  720. package/dist/components/message-feedback/message-feedback.class.d.ts.map +1 -0
  721. package/dist/components/message-feedback/message-feedback.class.js +266 -0
  722. package/dist/components/message-feedback/message-feedback.class.js.map +1 -0
  723. package/dist/components/message-feedback/message-feedback.d.ts +2 -0
  724. package/dist/components/message-feedback/message-feedback.d.ts.map +1 -0
  725. package/dist/components/message-feedback/message-feedback.js +5 -0
  726. package/dist/components/message-feedback/message-feedback.js.map +1 -0
  727. package/dist/components/message-feedback/message-feedback.styles.d.ts +2 -0
  728. package/dist/components/message-feedback/message-feedback.styles.d.ts.map +1 -0
  729. package/dist/components/message-feedback/message-feedback.styles.js +133 -0
  730. package/dist/components/message-feedback/message-feedback.styles.js.map +1 -0
  731. package/dist/components/mind-map/mind-map-layout.d.ts +52 -0
  732. package/dist/components/mind-map/mind-map-layout.d.ts.map +1 -0
  733. package/dist/components/mind-map/mind-map-layout.js +69 -0
  734. package/dist/components/mind-map/mind-map-layout.js.map +1 -0
  735. package/dist/components/mind-map/mind-map.class.d.ts +83 -0
  736. package/dist/components/mind-map/mind-map.class.d.ts.map +1 -0
  737. package/dist/components/mind-map/mind-map.class.js +252 -0
  738. package/dist/components/mind-map/mind-map.class.js.map +1 -0
  739. package/dist/components/mind-map/mind-map.d.ts +2 -0
  740. package/dist/components/mind-map/mind-map.d.ts.map +1 -0
  741. package/dist/components/mind-map/mind-map.js +5 -0
  742. package/dist/components/mind-map/mind-map.js.map +1 -0
  743. package/dist/components/mind-map/mind-map.styles.d.ts +2 -0
  744. package/dist/components/mind-map/mind-map.styles.d.ts.map +1 -0
  745. package/dist/components/mind-map/mind-map.styles.js +43 -0
  746. package/dist/components/mind-map/mind-map.styles.js.map +1 -0
  747. package/dist/components/model-select/model-select.class.d.ts +1 -0
  748. package/dist/components/model-select/model-select.class.d.ts.map +1 -1
  749. package/dist/components/model-select/model-select.class.js +13 -0
  750. package/dist/components/model-select/model-select.class.js.map +1 -1
  751. package/dist/components/mutation-observer/mutation-observer.class.d.ts +1 -0
  752. package/dist/components/mutation-observer/mutation-observer.class.d.ts.map +1 -1
  753. package/dist/components/mutation-observer/mutation-observer.class.js +15 -0
  754. package/dist/components/mutation-observer/mutation-observer.class.js.map +1 -1
  755. package/dist/components/neighbor-list/neighbor-list.class.d.ts +70 -0
  756. package/dist/components/neighbor-list/neighbor-list.class.d.ts.map +1 -0
  757. package/dist/components/neighbor-list/neighbor-list.class.js +177 -0
  758. package/dist/components/neighbor-list/neighbor-list.class.js.map +1 -0
  759. package/dist/components/neighbor-list/neighbor-list.d.ts +4 -0
  760. package/dist/components/neighbor-list/neighbor-list.d.ts.map +1 -0
  761. package/dist/components/neighbor-list/neighbor-list.js +7 -0
  762. package/dist/components/neighbor-list/neighbor-list.js.map +1 -0
  763. package/dist/components/neighbor-list/neighbor-list.styles.d.ts +2 -0
  764. package/dist/components/neighbor-list/neighbor-list.styles.d.ts.map +1 -0
  765. package/dist/components/neighbor-list/neighbor-list.styles.js +79 -0
  766. package/dist/components/neighbor-list/neighbor-list.styles.js.map +1 -0
  767. package/dist/components/node-palette/node-palette.class.d.ts +82 -0
  768. package/dist/components/node-palette/node-palette.class.d.ts.map +1 -0
  769. package/dist/components/node-palette/node-palette.class.js +213 -0
  770. package/dist/components/node-palette/node-palette.class.js.map +1 -0
  771. package/dist/components/node-palette/node-palette.d.ts +2 -0
  772. package/dist/components/node-palette/node-palette.d.ts.map +1 -0
  773. package/dist/components/node-palette/node-palette.js +5 -0
  774. package/dist/components/node-palette/node-palette.js.map +1 -0
  775. package/dist/components/node-palette/node-palette.styles.d.ts +2 -0
  776. package/dist/components/node-palette/node-palette.styles.d.ts.map +1 -0
  777. package/dist/components/node-palette/node-palette.styles.js +74 -0
  778. package/dist/components/node-palette/node-palette.styles.js.map +1 -0
  779. package/dist/components/notebook-viewer/dompurify-loader.d.ts +7 -0
  780. package/dist/components/notebook-viewer/dompurify-loader.d.ts.map +1 -0
  781. package/dist/components/notebook-viewer/dompurify-loader.js +23 -0
  782. package/dist/components/notebook-viewer/dompurify-loader.js.map +1 -0
  783. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts +164 -0
  784. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts.map +1 -0
  785. package/dist/components/notebook-viewer/notebook-viewer.class.js +442 -0
  786. package/dist/components/notebook-viewer/notebook-viewer.class.js.map +1 -0
  787. package/dist/components/notebook-viewer/notebook-viewer.d.ts +6 -0
  788. package/dist/components/notebook-viewer/notebook-viewer.d.ts.map +1 -0
  789. package/dist/components/notebook-viewer/notebook-viewer.js +21 -0
  790. package/dist/components/notebook-viewer/notebook-viewer.js.map +1 -0
  791. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts +2 -0
  792. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts.map +1 -0
  793. package/dist/components/notebook-viewer/notebook-viewer.styles.js +79 -0
  794. package/dist/components/notebook-viewer/notebook-viewer.styles.js.map +1 -0
  795. package/dist/components/overlay/overlay.styles.d.ts.map +1 -1
  796. package/dist/components/overlay/overlay.styles.js +17 -5
  797. package/dist/components/overlay/overlay.styles.js.map +1 -1
  798. package/dist/components/overlay/popover.class.d.ts +2 -0
  799. package/dist/components/overlay/popover.class.d.ts.map +1 -1
  800. package/dist/components/overlay/popover.class.js +10 -2
  801. package/dist/components/overlay/popover.class.js.map +1 -1
  802. package/dist/components/overlay/tooltip.class.d.ts +4 -0
  803. package/dist/components/overlay/tooltip.class.d.ts.map +1 -1
  804. package/dist/components/overlay/tooltip.class.js +21 -6
  805. package/dist/components/overlay/tooltip.class.js.map +1 -1
  806. package/dist/components/page-rail/page-rail.class.d.ts +99 -0
  807. package/dist/components/page-rail/page-rail.class.d.ts.map +1 -0
  808. package/dist/components/page-rail/page-rail.class.js +279 -0
  809. package/dist/components/page-rail/page-rail.class.js.map +1 -0
  810. package/dist/components/page-rail/page-rail.d.ts +2 -0
  811. package/dist/components/page-rail/page-rail.d.ts.map +1 -0
  812. package/dist/components/page-rail/page-rail.js +5 -0
  813. package/dist/components/page-rail/page-rail.js.map +1 -0
  814. package/dist/components/page-rail/page-rail.styles.d.ts +2 -0
  815. package/dist/components/page-rail/page-rail.styles.d.ts.map +1 -0
  816. package/dist/components/page-rail/page-rail.styles.js +85 -0
  817. package/dist/components/page-rail/page-rail.styles.js.map +1 -0
  818. package/dist/components/pagination/pagination.class.d.ts +5 -0
  819. package/dist/components/pagination/pagination.class.d.ts.map +1 -1
  820. package/dist/components/pagination/pagination.class.js +11 -9
  821. package/dist/components/pagination/pagination.class.js.map +1 -1
  822. package/dist/components/path-strip/path-strip.class.d.ts +61 -0
  823. package/dist/components/path-strip/path-strip.class.d.ts.map +1 -0
  824. package/dist/components/path-strip/path-strip.class.js +164 -0
  825. package/dist/components/path-strip/path-strip.class.js.map +1 -0
  826. package/dist/components/path-strip/path-strip.d.ts +3 -0
  827. package/dist/components/path-strip/path-strip.d.ts.map +1 -0
  828. package/dist/components/path-strip/path-strip.js +6 -0
  829. package/dist/components/path-strip/path-strip.js.map +1 -0
  830. package/dist/components/path-strip/path-strip.styles.d.ts +2 -0
  831. package/dist/components/path-strip/path-strip.styles.d.ts.map +1 -0
  832. package/dist/components/path-strip/path-strip.styles.js +62 -0
  833. package/dist/components/path-strip/path-strip.styles.js.map +1 -0
  834. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts +145 -6
  835. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts.map +1 -1
  836. package/dist/components/pdf-viewer/pdf-viewer.class.js +785 -21
  837. package/dist/components/pdf-viewer/pdf-viewer.class.js.map +1 -1
  838. package/dist/components/pdf-viewer/pdf-viewer.js +7 -1
  839. package/dist/components/pdf-viewer/pdf-viewer.js.map +1 -1
  840. package/dist/components/pdf-viewer/pdf-viewer.styles.d.ts.map +1 -1
  841. package/dist/components/pdf-viewer/pdf-viewer.styles.js +4 -0
  842. package/dist/components/pdf-viewer/pdf-viewer.styles.js.map +1 -1
  843. package/dist/components/phone-input/phone-input.class.d.ts.map +1 -1
  844. package/dist/components/phone-input/phone-input.class.js +5 -1
  845. package/dist/components/phone-input/phone-input.class.js.map +1 -1
  846. package/dist/components/playback/playback.styles.d.ts.map +1 -1
  847. package/dist/components/playback/playback.styles.js +7 -0
  848. package/dist/components/playback/playback.styles.js.map +1 -1
  849. package/dist/components/poll-status/poll-status.class.d.ts +1 -0
  850. package/dist/components/poll-status/poll-status.class.d.ts.map +1 -1
  851. package/dist/components/poll-status/poll-status.class.js +25 -7
  852. package/dist/components/poll-status/poll-status.class.js.map +1 -1
  853. package/dist/components/pptx-viewer/pptx-viewer.styles.d.ts.map +1 -1
  854. package/dist/components/pptx-viewer/pptx-viewer.styles.js +5 -0
  855. package/dist/components/pptx-viewer/pptx-viewer.styles.js.map +1 -1
  856. package/dist/components/progress/progress-bar.class.d.ts +5 -0
  857. package/dist/components/progress/progress-bar.class.d.ts.map +1 -1
  858. package/dist/components/progress/progress-bar.class.js +16 -2
  859. package/dist/components/progress/progress-bar.class.js.map +1 -1
  860. package/dist/components/progress/progress-ring.class.d.ts +5 -0
  861. package/dist/components/progress/progress-ring.class.d.ts.map +1 -1
  862. package/dist/components/progress/progress-ring.class.js +16 -2
  863. package/dist/components/progress/progress-ring.class.js.map +1 -1
  864. package/dist/components/progress/progress.styles.d.ts.map +1 -1
  865. package/dist/components/progress/progress.styles.js +6 -0
  866. package/dist/components/progress/progress.styles.js.map +1 -1
  867. package/dist/components/provenance-panel/provenance-panel.class.d.ts +71 -0
  868. package/dist/components/provenance-panel/provenance-panel.class.d.ts.map +1 -0
  869. package/dist/components/provenance-panel/provenance-panel.class.js +110 -0
  870. package/dist/components/provenance-panel/provenance-panel.class.js.map +1 -0
  871. package/dist/components/provenance-panel/provenance-panel.d.ts +7 -0
  872. package/dist/components/provenance-panel/provenance-panel.d.ts.map +1 -0
  873. package/dist/components/provenance-panel/provenance-panel.js +10 -0
  874. package/dist/components/provenance-panel/provenance-panel.js.map +1 -0
  875. package/dist/components/provenance-panel/provenance-panel.styles.d.ts +2 -0
  876. package/dist/components/provenance-panel/provenance-panel.styles.d.ts.map +1 -0
  877. package/dist/components/provenance-panel/provenance-panel.styles.js +45 -0
  878. package/dist/components/provenance-panel/provenance-panel.styles.js.map +1 -0
  879. package/dist/components/push-to-talk/push-to-talk.class.d.ts +145 -0
  880. package/dist/components/push-to-talk/push-to-talk.class.d.ts.map +1 -0
  881. package/dist/components/push-to-talk/push-to-talk.class.js +478 -0
  882. package/dist/components/push-to-talk/push-to-talk.class.js.map +1 -0
  883. package/dist/components/push-to-talk/push-to-talk.d.ts +3 -0
  884. package/dist/components/push-to-talk/push-to-talk.d.ts.map +1 -0
  885. package/dist/components/push-to-talk/push-to-talk.js +6 -0
  886. package/dist/components/push-to-talk/push-to-talk.js.map +1 -0
  887. package/dist/components/push-to-talk/push-to-talk.styles.d.ts +2 -0
  888. package/dist/components/push-to-talk/push-to-talk.styles.d.ts.map +1 -0
  889. package/dist/components/push-to-talk/push-to-talk.styles.js +79 -0
  890. package/dist/components/push-to-talk/push-to-talk.styles.js.map +1 -0
  891. package/dist/components/radio/radio.class.d.ts +1 -0
  892. package/dist/components/radio/radio.class.d.ts.map +1 -1
  893. package/dist/components/radio/radio.class.js +4 -0
  894. package/dist/components/radio/radio.class.js.map +1 -1
  895. package/dist/components/random-content/random-content.class.d.ts +3 -1
  896. package/dist/components/random-content/random-content.class.d.ts.map +1 -1
  897. package/dist/components/random-content/random-content.class.js +7 -4
  898. package/dist/components/random-content/random-content.class.js.map +1 -1
  899. package/dist/components/rating/rating.class.d.ts +8 -0
  900. package/dist/components/rating/rating.class.d.ts.map +1 -1
  901. package/dist/components/rating/rating.class.js +34 -8
  902. package/dist/components/rating/rating.class.js.map +1 -1
  903. package/dist/components/rubric-form/rubric-form.class.d.ts +195 -0
  904. package/dist/components/rubric-form/rubric-form.class.d.ts.map +1 -0
  905. package/dist/components/rubric-form/rubric-form.class.js +495 -0
  906. package/dist/components/rubric-form/rubric-form.class.js.map +1 -0
  907. package/dist/components/rubric-form/rubric-form.d.ts +9 -0
  908. package/dist/components/rubric-form/rubric-form.d.ts.map +1 -0
  909. package/dist/components/rubric-form/rubric-form.js +12 -0
  910. package/dist/components/rubric-form/rubric-form.js.map +1 -0
  911. package/dist/components/rubric-form/rubric-form.styles.d.ts +2 -0
  912. package/dist/components/rubric-form/rubric-form.styles.d.ts.map +1 -0
  913. package/dist/components/rubric-form/rubric-form.styles.js +90 -0
  914. package/dist/components/rubric-form/rubric-form.styles.js.map +1 -0
  915. package/dist/components/scroller/scroller.class.d.ts +6 -0
  916. package/dist/components/scroller/scroller.class.d.ts.map +1 -1
  917. package/dist/components/scroller/scroller.class.js +14 -4
  918. package/dist/components/scroller/scroller.class.js.map +1 -1
  919. package/dist/components/scroller/scroller.styles.d.ts.map +1 -1
  920. package/dist/components/scroller/scroller.styles.js +18 -0
  921. package/dist/components/scroller/scroller.styles.js.map +1 -1
  922. package/dist/components/segmented/segmented.class.d.ts +1 -0
  923. package/dist/components/segmented/segmented.class.d.ts.map +1 -1
  924. package/dist/components/segmented/segmented.class.js +1 -0
  925. package/dist/components/segmented/segmented.class.js.map +1 -1
  926. package/dist/components/segmented/segmented.styles.d.ts.map +1 -1
  927. package/dist/components/segmented/segmented.styles.js +21 -3
  928. package/dist/components/segmented/segmented.styles.js.map +1 -1
  929. package/dist/components/sequence-strip/sequence-strip.class.d.ts +62 -0
  930. package/dist/components/sequence-strip/sequence-strip.class.d.ts.map +1 -0
  931. package/dist/components/sequence-strip/sequence-strip.class.js +102 -0
  932. package/dist/components/sequence-strip/sequence-strip.class.js.map +1 -0
  933. package/dist/components/sequence-strip/sequence-strip.d.ts +2 -0
  934. package/dist/components/sequence-strip/sequence-strip.d.ts.map +1 -0
  935. package/dist/components/sequence-strip/sequence-strip.js +5 -0
  936. package/dist/components/sequence-strip/sequence-strip.js.map +1 -0
  937. package/dist/components/sequence-strip/sequence-strip.styles.d.ts +2 -0
  938. package/dist/components/sequence-strip/sequence-strip.styles.d.ts.map +1 -0
  939. package/dist/components/sequence-strip/sequence-strip.styles.js +62 -0
  940. package/dist/components/sequence-strip/sequence-strip.styles.js.map +1 -0
  941. package/dist/components/skeleton/skeleton.styles.d.ts.map +1 -1
  942. package/dist/components/skeleton/skeleton.styles.js +7 -0
  943. package/dist/components/skeleton/skeleton.styles.js.map +1 -1
  944. package/dist/components/slider/slider.class.d.ts +6 -1
  945. package/dist/components/slider/slider.class.d.ts.map +1 -1
  946. package/dist/components/slider/slider.class.js +23 -6
  947. package/dist/components/slider/slider.class.js.map +1 -1
  948. package/dist/components/slider/slider.styles.d.ts.map +1 -1
  949. package/dist/components/slider/slider.styles.js +15 -0
  950. package/dist/components/slider/slider.styles.js.map +1 -1
  951. package/dist/components/source-picker/source-picker.class.d.ts +78 -0
  952. package/dist/components/source-picker/source-picker.class.d.ts.map +1 -0
  953. package/dist/components/source-picker/source-picker.class.js +305 -0
  954. package/dist/components/source-picker/source-picker.class.js.map +1 -0
  955. package/dist/components/source-picker/source-picker.d.ts +5 -0
  956. package/dist/components/source-picker/source-picker.d.ts.map +1 -0
  957. package/dist/components/source-picker/source-picker.js +8 -0
  958. package/dist/components/source-picker/source-picker.js.map +1 -0
  959. package/dist/components/source-picker/source-picker.styles.d.ts +2 -0
  960. package/dist/components/source-picker/source-picker.styles.d.ts.map +1 -0
  961. package/dist/components/source-picker/source-picker.styles.js +80 -0
  962. package/dist/components/source-picker/source-picker.styles.js.map +1 -0
  963. package/dist/components/span-waterfall/span-waterfall.class.d.ts +70 -0
  964. package/dist/components/span-waterfall/span-waterfall.class.d.ts.map +1 -0
  965. package/dist/components/span-waterfall/span-waterfall.class.js +307 -0
  966. package/dist/components/span-waterfall/span-waterfall.class.js.map +1 -0
  967. package/dist/components/span-waterfall/span-waterfall.d.ts +4 -0
  968. package/dist/components/span-waterfall/span-waterfall.d.ts.map +1 -0
  969. package/dist/components/span-waterfall/span-waterfall.js +7 -0
  970. package/dist/components/span-waterfall/span-waterfall.js.map +1 -0
  971. package/dist/components/span-waterfall/span-waterfall.styles.d.ts +2 -0
  972. package/dist/components/span-waterfall/span-waterfall.styles.d.ts.map +1 -0
  973. package/dist/components/span-waterfall/span-waterfall.styles.js +130 -0
  974. package/dist/components/span-waterfall/span-waterfall.styles.js.map +1 -0
  975. package/dist/components/sparkline/sparkline.class.d.ts.map +1 -1
  976. package/dist/components/sparkline/sparkline.class.js +17 -7
  977. package/dist/components/sparkline/sparkline.class.js.map +1 -1
  978. package/dist/components/split/split.class.d.ts +13 -0
  979. package/dist/components/split/split.class.d.ts.map +1 -1
  980. package/dist/components/split/split.class.js +24 -4
  981. package/dist/components/split/split.class.js.map +1 -1
  982. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js +1 -1
  983. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js.map +1 -1
  984. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts +93 -3
  985. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts.map +1 -1
  986. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js +241 -9
  987. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js.map +1 -1
  988. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js +10 -1
  989. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js.map +1 -1
  990. package/dist/components/stack-trace/stack-trace-parse.d.ts +22 -0
  991. package/dist/components/stack-trace/stack-trace-parse.d.ts.map +1 -0
  992. package/dist/components/stack-trace/stack-trace-parse.js +194 -0
  993. package/dist/components/stack-trace/stack-trace-parse.js.map +1 -0
  994. package/dist/components/stack-trace/stack-trace.class.d.ts +68 -0
  995. package/dist/components/stack-trace/stack-trace.class.d.ts.map +1 -0
  996. package/dist/components/stack-trace/stack-trace.class.js +193 -0
  997. package/dist/components/stack-trace/stack-trace.class.js.map +1 -0
  998. package/dist/components/stack-trace/stack-trace.d.ts +3 -0
  999. package/dist/components/stack-trace/stack-trace.d.ts.map +1 -0
  1000. package/dist/components/stack-trace/stack-trace.js +6 -0
  1001. package/dist/components/stack-trace/stack-trace.js.map +1 -0
  1002. package/dist/components/stack-trace/stack-trace.styles.d.ts +2 -0
  1003. package/dist/components/stack-trace/stack-trace.styles.d.ts.map +1 -0
  1004. package/dist/components/stack-trace/stack-trace.styles.js +101 -0
  1005. package/dist/components/stack-trace/stack-trace.styles.js.map +1 -0
  1006. package/dist/components/stat/stat.class.d.ts +10 -1
  1007. package/dist/components/stat/stat.class.d.ts.map +1 -1
  1008. package/dist/components/stat/stat.class.js +22 -7
  1009. package/dist/components/stat/stat.class.js.map +1 -1
  1010. package/dist/components/stepper/stepper.class.d.ts +5 -0
  1011. package/dist/components/stepper/stepper.class.d.ts.map +1 -1
  1012. package/dist/components/stepper/stepper.class.js +9 -1
  1013. package/dist/components/stepper/stepper.class.js.map +1 -1
  1014. package/dist/components/stream-status/stream-status.class.d.ts.map +1 -1
  1015. package/dist/components/stream-status/stream-status.class.js +9 -1
  1016. package/dist/components/stream-status/stream-status.class.js.map +1 -1
  1017. package/dist/components/streaming-text/streaming-text.class.d.ts +6 -0
  1018. package/dist/components/streaming-text/streaming-text.class.d.ts.map +1 -1
  1019. package/dist/components/streaming-text/streaming-text.class.js +22 -3
  1020. package/dist/components/streaming-text/streaming-text.class.js.map +1 -1
  1021. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts +54 -0
  1022. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts.map +1 -0
  1023. package/dist/components/suggestion-chips/suggestion-chips.class.js +120 -0
  1024. package/dist/components/suggestion-chips/suggestion-chips.class.js.map +1 -0
  1025. package/dist/components/suggestion-chips/suggestion-chips.d.ts +3 -0
  1026. package/dist/components/suggestion-chips/suggestion-chips.d.ts.map +1 -0
  1027. package/dist/components/suggestion-chips/suggestion-chips.js +6 -0
  1028. package/dist/components/suggestion-chips/suggestion-chips.js.map +1 -0
  1029. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts +2 -0
  1030. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts.map +1 -0
  1031. package/dist/components/suggestion-chips/suggestion-chips.styles.js +60 -0
  1032. package/dist/components/suggestion-chips/suggestion-chips.styles.js.map +1 -0
  1033. package/dist/components/svg-viewer/svg-viewer.class.d.ts +34 -0
  1034. package/dist/components/svg-viewer/svg-viewer.class.d.ts.map +1 -1
  1035. package/dist/components/svg-viewer/svg-viewer.class.js +88 -1
  1036. package/dist/components/svg-viewer/svg-viewer.class.js.map +1 -1
  1037. package/dist/components/svg-viewer/svg-viewer.js +1 -0
  1038. package/dist/components/svg-viewer/svg-viewer.js.map +1 -1
  1039. package/dist/components/svg-viewer/svg-viewer.styles.d.ts.map +1 -1
  1040. package/dist/components/svg-viewer/svg-viewer.styles.js +18 -0
  1041. package/dist/components/svg-viewer/svg-viewer.styles.js.map +1 -1
  1042. package/dist/components/swatch-picker/swatch-picker.class.d.ts +18 -2
  1043. package/dist/components/swatch-picker/swatch-picker.class.d.ts.map +1 -1
  1044. package/dist/components/swatch-picker/swatch-picker.class.js +17 -3
  1045. package/dist/components/swatch-picker/swatch-picker.class.js.map +1 -1
  1046. package/dist/components/swatch-picker/swatch-picker.styles.d.ts.map +1 -1
  1047. package/dist/components/swatch-picker/swatch-picker.styles.js +84 -8
  1048. package/dist/components/swatch-picker/swatch-picker.styles.js.map +1 -1
  1049. package/dist/components/table/table.class.d.ts +85 -5
  1050. package/dist/components/table/table.class.d.ts.map +1 -1
  1051. package/dist/components/table/table.class.js +254 -41
  1052. package/dist/components/table/table.class.js.map +1 -1
  1053. package/dist/components/table/table.styles.d.ts.map +1 -1
  1054. package/dist/components/table/table.styles.js +35 -0
  1055. package/dist/components/table/table.styles.js.map +1 -1
  1056. package/dist/components/tabs/tabs.class.d.ts +6 -0
  1057. package/dist/components/tabs/tabs.class.d.ts.map +1 -1
  1058. package/dist/components/tabs/tabs.class.js +10 -1
  1059. package/dist/components/tabs/tabs.class.js.map +1 -1
  1060. package/dist/components/tabs/tabs.styles.d.ts.map +1 -1
  1061. package/dist/components/tabs/tabs.styles.js +15 -0
  1062. package/dist/components/tabs/tabs.styles.js.map +1 -1
  1063. package/dist/components/task-list/task-list.class.d.ts +89 -0
  1064. package/dist/components/task-list/task-list.class.d.ts.map +1 -0
  1065. package/dist/components/task-list/task-list.class.js +271 -0
  1066. package/dist/components/task-list/task-list.class.js.map +1 -0
  1067. package/dist/components/task-list/task-list.d.ts +2 -0
  1068. package/dist/components/task-list/task-list.d.ts.map +1 -0
  1069. package/dist/components/task-list/task-list.js +5 -0
  1070. package/dist/components/task-list/task-list.js.map +1 -0
  1071. package/dist/components/task-list/task-list.styles.d.ts +2 -0
  1072. package/dist/components/task-list/task-list.styles.d.ts.map +1 -0
  1073. package/dist/components/task-list/task-list.styles.js +134 -0
  1074. package/dist/components/task-list/task-list.styles.js.map +1 -0
  1075. package/dist/components/terminal/terminal.class.d.ts +150 -0
  1076. package/dist/components/terminal/terminal.class.d.ts.map +1 -0
  1077. package/dist/components/terminal/terminal.class.js +565 -0
  1078. package/dist/components/terminal/terminal.class.js.map +1 -0
  1079. package/dist/components/terminal/terminal.d.ts +2 -0
  1080. package/dist/components/terminal/terminal.d.ts.map +1 -0
  1081. package/dist/components/terminal/terminal.js +5 -0
  1082. package/dist/components/terminal/terminal.js.map +1 -0
  1083. package/dist/components/terminal/terminal.styles.d.ts +2 -0
  1084. package/dist/components/terminal/terminal.styles.d.ts.map +1 -0
  1085. package/dist/components/terminal/terminal.styles.js +77 -0
  1086. package/dist/components/terminal/terminal.styles.js.map +1 -0
  1087. package/dist/components/test-results/test-results.class.d.ts +99 -0
  1088. package/dist/components/test-results/test-results.class.d.ts.map +1 -0
  1089. package/dist/components/test-results/test-results.class.js +276 -0
  1090. package/dist/components/test-results/test-results.class.js.map +1 -0
  1091. package/dist/components/test-results/test-results.d.ts +2 -0
  1092. package/dist/components/test-results/test-results.d.ts.map +1 -0
  1093. package/dist/components/test-results/test-results.js +5 -0
  1094. package/dist/components/test-results/test-results.js.map +1 -0
  1095. package/dist/components/test-results/test-results.styles.d.ts +2 -0
  1096. package/dist/components/test-results/test-results.styles.d.ts.map +1 -0
  1097. package/dist/components/test-results/test-results.styles.js +118 -0
  1098. package/dist/components/test-results/test-results.styles.js.map +1 -0
  1099. package/dist/components/textarea/textarea.class.d.ts.map +1 -1
  1100. package/dist/components/textarea/textarea.class.js +4 -0
  1101. package/dist/components/textarea/textarea.class.js.map +1 -1
  1102. package/dist/components/thinking-panel/thinking-panel.class.d.ts +6 -0
  1103. package/dist/components/thinking-panel/thinking-panel.class.d.ts.map +1 -1
  1104. package/dist/components/thinking-panel/thinking-panel.class.js +12 -2
  1105. package/dist/components/thinking-panel/thinking-panel.class.js.map +1 -1
  1106. package/dist/components/thread-list/thread-list.class.d.ts +140 -0
  1107. package/dist/components/thread-list/thread-list.class.d.ts.map +1 -0
  1108. package/dist/components/thread-list/thread-list.class.js +488 -0
  1109. package/dist/components/thread-list/thread-list.class.js.map +1 -0
  1110. package/dist/components/thread-list/thread-list.d.ts +5 -0
  1111. package/dist/components/thread-list/thread-list.d.ts.map +1 -0
  1112. package/dist/components/thread-list/thread-list.js +8 -0
  1113. package/dist/components/thread-list/thread-list.js.map +1 -0
  1114. package/dist/components/thread-list/thread-list.styles.d.ts +2 -0
  1115. package/dist/components/thread-list/thread-list.styles.d.ts.map +1 -0
  1116. package/dist/components/thread-list/thread-list.styles.js +81 -0
  1117. package/dist/components/thread-list/thread-list.styles.js.map +1 -0
  1118. package/dist/components/time-range/time-range.class.d.ts.map +1 -1
  1119. package/dist/components/time-range/time-range.class.js +3 -3
  1120. package/dist/components/time-range/time-range.class.js.map +1 -1
  1121. package/dist/components/timeline/timeline-item.class.d.ts.map +1 -1
  1122. package/dist/components/timeline/timeline-item.class.js +2 -1
  1123. package/dist/components/timeline/timeline-item.class.js.map +1 -1
  1124. package/dist/components/toast/toast-item.class.d.ts +8 -0
  1125. package/dist/components/toast/toast-item.class.d.ts.map +1 -1
  1126. package/dist/components/toast/toast-item.class.js +14 -2
  1127. package/dist/components/toast/toast-item.class.js.map +1 -1
  1128. package/dist/components/toast/toast-item.styles.d.ts.map +1 -1
  1129. package/dist/components/toast/toast-item.styles.js +2 -0
  1130. package/dist/components/toast/toast-item.styles.js.map +1 -1
  1131. package/dist/components/token-input/token-input.class.d.ts +29 -3
  1132. package/dist/components/token-input/token-input.class.d.ts.map +1 -1
  1133. package/dist/components/token-input/token-input.class.js +41 -13
  1134. package/dist/components/token-input/token-input.class.js.map +1 -1
  1135. package/dist/components/token-input/token-input.styles.d.ts.map +1 -1
  1136. package/dist/components/token-input/token-input.styles.js +6 -1
  1137. package/dist/components/token-input/token-input.styles.js.map +1 -1
  1138. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts +6 -0
  1139. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts.map +1 -1
  1140. package/dist/components/tool-call-chip/tool-call-chip.class.js +15 -4
  1141. package/dist/components/tool-call-chip/tool-call-chip.class.js.map +1 -1
  1142. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts +6 -0
  1143. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts.map +1 -1
  1144. package/dist/components/tool-result-dialog/tool-result-dialog.class.js +12 -3
  1145. package/dist/components/tool-result-dialog/tool-result-dialog.class.js.map +1 -1
  1146. package/dist/components/tour/tour.class.d.ts +6 -3
  1147. package/dist/components/tour/tour.class.d.ts.map +1 -1
  1148. package/dist/components/tour/tour.class.js +56 -20
  1149. package/dist/components/tour/tour.class.js.map +1 -1
  1150. package/dist/components/trace-tree/span.d.ts +26 -0
  1151. package/dist/components/trace-tree/span.d.ts.map +1 -0
  1152. package/dist/components/trace-tree/span.js +2 -0
  1153. package/dist/components/trace-tree/span.js.map +1 -0
  1154. package/dist/components/trace-tree/trace-tree.class.d.ts +85 -0
  1155. package/dist/components/trace-tree/trace-tree.class.d.ts.map +1 -0
  1156. package/dist/components/trace-tree/trace-tree.class.js +443 -0
  1157. package/dist/components/trace-tree/trace-tree.class.js.map +1 -0
  1158. package/dist/components/trace-tree/trace-tree.d.ts +5 -0
  1159. package/dist/components/trace-tree/trace-tree.d.ts.map +1 -0
  1160. package/dist/components/trace-tree/trace-tree.js +8 -0
  1161. package/dist/components/trace-tree/trace-tree.js.map +1 -0
  1162. package/dist/components/trace-tree/trace-tree.styles.d.ts +2 -0
  1163. package/dist/components/trace-tree/trace-tree.styles.d.ts.map +1 -0
  1164. package/dist/components/trace-tree/trace-tree.styles.js +186 -0
  1165. package/dist/components/trace-tree/trace-tree.styles.js.map +1 -0
  1166. package/dist/components/transcript-feed/transcript-feed.class.d.ts +89 -0
  1167. package/dist/components/transcript-feed/transcript-feed.class.d.ts.map +1 -0
  1168. package/dist/components/transcript-feed/transcript-feed.class.js +188 -0
  1169. package/dist/components/transcript-feed/transcript-feed.class.js.map +1 -0
  1170. package/dist/components/transcript-feed/transcript-feed.d.ts +2 -0
  1171. package/dist/components/transcript-feed/transcript-feed.d.ts.map +1 -0
  1172. package/dist/components/transcript-feed/transcript-feed.js +5 -0
  1173. package/dist/components/transcript-feed/transcript-feed.js.map +1 -0
  1174. package/dist/components/transcript-feed/transcript-feed.styles.d.ts +2 -0
  1175. package/dist/components/transcript-feed/transcript-feed.styles.d.ts.map +1 -0
  1176. package/dist/components/transcript-feed/transcript-feed.styles.js +94 -0
  1177. package/dist/components/transcript-feed/transcript-feed.styles.js.map +1 -0
  1178. package/dist/components/tree/tree-node.class.d.ts +25 -4
  1179. package/dist/components/tree/tree-node.class.d.ts.map +1 -1
  1180. package/dist/components/tree/tree-node.class.js +61 -11
  1181. package/dist/components/tree/tree-node.class.js.map +1 -1
  1182. package/dist/components/tree/tree-node.styles.d.ts.map +1 -1
  1183. package/dist/components/tree/tree-node.styles.js +34 -5
  1184. package/dist/components/tree/tree-node.styles.js.map +1 -1
  1185. package/dist/components/tree/tree.class.d.ts +9 -0
  1186. package/dist/components/tree/tree.class.d.ts.map +1 -1
  1187. package/dist/components/tree/tree.class.js.map +1 -1
  1188. package/dist/components/usage-badge/usage-badge.class.d.ts +87 -0
  1189. package/dist/components/usage-badge/usage-badge.class.d.ts.map +1 -0
  1190. package/dist/components/usage-badge/usage-badge.class.js +246 -0
  1191. package/dist/components/usage-badge/usage-badge.class.js.map +1 -0
  1192. package/dist/components/usage-badge/usage-badge.d.ts +2 -0
  1193. package/dist/components/usage-badge/usage-badge.d.ts.map +1 -0
  1194. package/dist/components/usage-badge/usage-badge.js +5 -0
  1195. package/dist/components/usage-badge/usage-badge.js.map +1 -0
  1196. package/dist/components/usage-badge/usage-badge.styles.d.ts +2 -0
  1197. package/dist/components/usage-badge/usage-badge.styles.d.ts.map +1 -0
  1198. package/dist/components/usage-badge/usage-badge.styles.js +62 -0
  1199. package/dist/components/usage-badge/usage-badge.styles.js.map +1 -0
  1200. package/dist/components/virtual-list/virtual-list.class.d.ts +62 -0
  1201. package/dist/components/virtual-list/virtual-list.class.d.ts.map +1 -1
  1202. package/dist/components/virtual-list/virtual-list.class.js +123 -8
  1203. package/dist/components/virtual-list/virtual-list.class.js.map +1 -1
  1204. package/dist/components/voice-picker/voice-picker.class.d.ts +241 -0
  1205. package/dist/components/voice-picker/voice-picker.class.d.ts.map +1 -0
  1206. package/dist/components/voice-picker/voice-picker.class.js +808 -0
  1207. package/dist/components/voice-picker/voice-picker.class.js.map +1 -0
  1208. package/dist/components/voice-picker/voice-picker.d.ts +2 -0
  1209. package/dist/components/voice-picker/voice-picker.d.ts.map +1 -0
  1210. package/dist/components/voice-picker/voice-picker.js +5 -0
  1211. package/dist/components/voice-picker/voice-picker.js.map +1 -0
  1212. package/dist/components/voice-picker/voice-picker.styles.d.ts +2 -0
  1213. package/dist/components/voice-picker/voice-picker.styles.d.ts.map +1 -0
  1214. package/dist/components/voice-picker/voice-picker.styles.js +272 -0
  1215. package/dist/components/voice-picker/voice-picker.styles.js.map +1 -0
  1216. package/dist/components/widget-renderer/default-registry.d.ts +14 -0
  1217. package/dist/components/widget-renderer/default-registry.d.ts.map +1 -0
  1218. package/dist/components/widget-renderer/default-registry.js +43 -0
  1219. package/dist/components/widget-renderer/default-registry.js.map +1 -0
  1220. package/dist/components/widget-renderer/registry.d.ts +31 -0
  1221. package/dist/components/widget-renderer/registry.d.ts.map +1 -0
  1222. package/dist/components/widget-renderer/registry.js +23 -0
  1223. package/dist/components/widget-renderer/registry.js.map +1 -0
  1224. package/dist/components/widget-renderer/resolve.d.ts +48 -0
  1225. package/dist/components/widget-renderer/resolve.d.ts.map +1 -0
  1226. package/dist/components/widget-renderer/resolve.js +122 -0
  1227. package/dist/components/widget-renderer/resolve.js.map +1 -0
  1228. package/dist/components/widget-renderer/widget-renderer.class.d.ts +67 -0
  1229. package/dist/components/widget-renderer/widget-renderer.class.d.ts.map +1 -0
  1230. package/dist/components/widget-renderer/widget-renderer.class.js +175 -0
  1231. package/dist/components/widget-renderer/widget-renderer.class.js.map +1 -0
  1232. package/dist/components/widget-renderer/widget-renderer.d.ts +5 -0
  1233. package/dist/components/widget-renderer/widget-renderer.d.ts.map +1 -0
  1234. package/dist/components/widget-renderer/widget-renderer.js +10 -0
  1235. package/dist/components/widget-renderer/widget-renderer.js.map +1 -0
  1236. package/dist/components/widget-renderer/widget-renderer.styles.d.ts +2 -0
  1237. package/dist/components/widget-renderer/widget-renderer.styles.d.ts.map +1 -0
  1238. package/dist/components/widget-renderer/widget-renderer.styles.js +14 -0
  1239. package/dist/components/widget-renderer/widget-renderer.styles.js.map +1 -0
  1240. package/dist/components/word-cloud/word-cloud-layout.d.ts +4 -0
  1241. package/dist/components/word-cloud/word-cloud-layout.d.ts.map +1 -1
  1242. package/dist/components/word-cloud/word-cloud-layout.js +3 -2
  1243. package/dist/components/word-cloud/word-cloud-layout.js.map +1 -1
  1244. package/dist/components/word-cloud/word-cloud.class.d.ts.map +1 -1
  1245. package/dist/components/word-cloud/word-cloud.class.js +11 -3
  1246. package/dist/components/word-cloud/word-cloud.class.js.map +1 -1
  1247. package/dist/components/xml-viewer/xml-viewer.class.d.ts +135 -0
  1248. package/dist/components/xml-viewer/xml-viewer.class.d.ts.map +1 -0
  1249. package/dist/components/xml-viewer/xml-viewer.class.js +0 -0
  1250. package/dist/components/xml-viewer/xml-viewer.class.js.map +1 -0
  1251. package/dist/components/xml-viewer/xml-viewer.d.ts +2 -0
  1252. package/dist/components/xml-viewer/xml-viewer.d.ts.map +1 -0
  1253. package/dist/components/xml-viewer/xml-viewer.js +20 -0
  1254. package/dist/components/xml-viewer/xml-viewer.js.map +1 -0
  1255. package/dist/components/xml-viewer/xml-viewer.styles.d.ts +2 -0
  1256. package/dist/components/xml-viewer/xml-viewer.styles.d.ts.map +1 -0
  1257. package/dist/components/xml-viewer/xml-viewer.styles.js +156 -0
  1258. package/dist/components/xml-viewer/xml-viewer.styles.js.map +1 -0
  1259. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts +14 -2
  1260. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts.map +1 -1
  1261. package/dist/components/zoomable-frame/zoomable-frame.class.js +30 -14
  1262. package/dist/components/zoomable-frame/zoomable-frame.class.js.map +1 -1
  1263. package/dist/internal/anchor-target.d.ts +49 -0
  1264. package/dist/internal/anchor-target.d.ts.map +1 -0
  1265. package/dist/internal/anchor-target.js +255 -0
  1266. package/dist/internal/anchor-target.js.map +1 -0
  1267. package/dist/internal/ansi.d.ts +35 -0
  1268. package/dist/internal/ansi.d.ts.map +1 -0
  1269. package/dist/internal/ansi.js +210 -0
  1270. package/dist/internal/ansi.js.map +1 -0
  1271. package/dist/internal/cell-range.d.ts +19 -0
  1272. package/dist/internal/cell-range.d.ts.map +1 -0
  1273. package/dist/internal/cell-range.js +69 -0
  1274. package/dist/internal/cell-range.js.map +1 -0
  1275. package/dist/internal/intl-cache.d.ts +33 -0
  1276. package/dist/internal/intl-cache.d.ts.map +1 -0
  1277. package/dist/internal/intl-cache.js +0 -0
  1278. package/dist/internal/intl-cache.js.map +1 -0
  1279. package/dist/internal/layered-layout.d.ts +44 -0
  1280. package/dist/internal/layered-layout.d.ts.map +1 -0
  1281. package/dist/internal/layered-layout.js +172 -0
  1282. package/dist/internal/layered-layout.js.map +1 -0
  1283. package/dist/internal/localization.d.ts +12 -1
  1284. package/dist/internal/localization.d.ts.map +1 -1
  1285. package/dist/internal/localization.js +366 -4
  1286. package/dist/internal/localization.js.map +1 -1
  1287. package/dist/internal/lyra-element.d.ts +10 -1
  1288. package/dist/internal/lyra-element.d.ts.map +1 -1
  1289. package/dist/internal/lyra-element.js +19 -1
  1290. package/dist/internal/lyra-element.js.map +1 -1
  1291. package/dist/internal/root-registration-allowlist.d.ts +2 -2
  1292. package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
  1293. package/dist/internal/root-registration-allowlist.js +55 -0
  1294. package/dist/internal/root-registration-allowlist.js.map +1 -1
  1295. package/dist/internal/slugger.d.ts +11 -0
  1296. package/dist/internal/slugger.d.ts.map +1 -0
  1297. package/dist/internal/slugger.js +45 -0
  1298. package/dist/internal/slugger.js.map +1 -0
  1299. package/dist/internal/text-highlights.d.ts +21 -0
  1300. package/dist/internal/text-highlights.d.ts.map +1 -0
  1301. package/dist/internal/text-highlights.js +172 -0
  1302. package/dist/internal/text-highlights.js.map +1 -0
  1303. package/dist/internal/text-quote.d.ts +53 -0
  1304. package/dist/internal/text-quote.d.ts.map +1 -0
  1305. package/dist/internal/text-quote.js +326 -0
  1306. package/dist/internal/text-quote.js.map +1 -0
  1307. package/dist/internal/tokens.styles.d.ts.map +1 -1
  1308. package/dist/internal/tokens.styles.js +49 -0
  1309. package/dist/internal/tokens.styles.js.map +1 -1
  1310. package/dist/internal/viewer-search.d.ts +18 -0
  1311. package/dist/internal/viewer-search.d.ts.map +1 -0
  1312. package/dist/internal/viewer-search.js +21 -0
  1313. package/dist/internal/viewer-search.js.map +1 -0
  1314. package/dist/lyra.d.ts +136 -2
  1315. package/dist/lyra.d.ts.map +1 -1
  1316. package/dist/lyra.js +109 -0
  1317. package/dist/lyra.js.map +1 -1
  1318. package/llms-full.txt +2713 -101
  1319. package/llms.txt +28 -1
  1320. package/package.json +135 -9
  1321. package/vscode-css-data.json +224 -0
  1322. package/vscode-html-data.json +5309 -2225
  1323. package/web-types.json +5803 -2513
package/llms-full.txt CHANGED
@@ -36,8 +36,8 @@ composition without registration; for example, `components/empty/empty.class.js`
36
36
  `lyra-model-settings-panel`, `lyra-context-meter`, `lyra-dock-panel`, `lyra-document-preview`,
37
37
  `lyra-document-viewer`, `lyra-docx-viewer`, `lyra-email-viewer`, `lyra-calendar-viewer`, `lyra-archive-viewer`,
38
38
  `lyra-media-card`, `lyra-attachment-trigger`, `lyra-kbd`, `lyra-result-card`/`lyra-result-field`,
39
- `lyra-avatar`, `lyra-card`, `lyra-stepper`, `lyra-segmented`, `lyra-diff-view`, `lyra-poll-status`,
40
- `lyra-code-block-core` (needs the optional peer `shiki`)
39
+ `lyra-avatar`, `lyra-card`, `lyra-stepper`, `lyra-segmented`, `lyra-diff-view`, `lyra-stack-trace`,
40
+ `lyra-poll-status`, `lyra-code-block-core` (needs the optional peer `shiki`)
41
41
  - **Cross-cutting notes** — packaging notes that apply across the whole library
42
42
 
43
43
  ---
@@ -805,8 +805,8 @@ form-associated via the same `FormAssociated` mixin as `lyra-textarea`. Ships th
805
805
  `size` scale as `lyra-select`/`lyra-combobox`.
806
806
 
807
807
  **Properties:**
808
- - `type: 'text' | 'password' | 'email' | 'number' | 'time' = 'text'`
809
- - `size: 'xs' | 's' | 'm' | 'l' | 'xl' = 'm'` (reflected)
808
+ - `type: 'text' | 'password' | 'email' | 'number' | 'time' | 'search' = 'text'`
809
+ - `size: '2xs' | 'xs' | 's' | 'm' | 'l' | 'xl' = 'm'` (reflected)
810
810
  - `value: string = ''` (from `FormAssociated`)
811
811
  - `placeholder: string = ''`
812
812
  - `label: string = ''`
@@ -1453,12 +1453,17 @@ accent edge and value tint).
1453
1453
  ## `lyra-table`
1454
1454
 
1455
1455
  Sort/select-aware data table. Sorting remains consumer-controlled; optional filtering, pagination,
1456
- and loading chrome are built in while remaining controlled at the public API boundary.
1456
+ and loading chrome are built in while remaining controlled at the public API boundary. A
1457
+ `columns[].heatValue`-opted-in heat-tint mode paints a shared, normalized color-mix background across
1458
+ every tinted cell (auto-derived domain, or overridden via `heatTintScale`); `rowTotal`/`grandTotal`
1459
+ add a trailing totals column mirroring `expandedContent`'s leading one — `rowTotal(row)` renders
1460
+ per-row, `grandTotal(rows)` renders at its intersection with the footer row — both sharing `footer`'s
1461
+ own "consumer computes/renders" contract rather than assuming addition.
1457
1462
 
1458
1463
  **Properties:**
1459
1464
  - `columns: TableColumn<T>[] = []` (attribute: false) — `{ key, label, headerCell?, width?,
1460
- minWidth?, sortable?, align?: 'start'|'end', priority?: 'medium'|'low', sticky?: boolean |
1461
- 'start' | 'end', footer?, cellStyle?, cell: (row) => unknown }` —
1465
+ minWidth?, resizable?, sortable?, align?: 'start'|'end', priority?: 'medium'|'low', sticky?: boolean |
1466
+ 'start' | 'end', footer?, cellStyle?, heatValue?, cell: (row) => unknown }` —
1462
1467
  `priority` progressively hides that column via a `@container` query as `[part='base']` narrows
1463
1468
  (`'low'` hides first, under a ~900px container width; `'medium'` next, under ~640px; both
1464
1469
  breakpoints are fixed in `table.styles.ts`, not themeable tokens), reversible via
@@ -1469,10 +1474,17 @@ and loading chrome are built in while remaining controlled at the public API bou
1469
1474
  sticky-bottom footer cell for that column, computed from every currently-rendered row (post-sort,
1470
1475
  pre-pagination) — e.g. a column total — omit it for a column with no footer value, and a
1471
1476
  `[part='foot']` (`<tfoot>`) only renders at all when at least one column defines `footer`;
1472
- `cellStyle` is applied directly to the generated `<td>` via `styleMap` e.g. a computed heat-tint
1477
+ `heatValue(row) => number | null | undefined` opts a column into heat-tint mode: its presence on
1478
+ any column is the opt-in signal (no separate boolean), a `null`/`undefined` return excludes that
1479
+ cell from both the domain and the tint ("no data", not "zero"), and every `heatValue`-defining
1480
+ column shares one normalized `color-mix()` background scale (see `heatTintScale` below) painted
1481
+ via the retheme-able `--lyra-table-heat-tint-lo`/`-hi` custom properties, matching `lyra-heatmap`'s
1482
+ own ramp-token convention; `cellStyle` is applied directly to the generated `<td>` via `styleMap` — e.g. a computed heat-tint
1473
1483
  background a `cell()`-returned inner element can't paint into the cell's own padding — omit it for
1474
1484
  no per-cell style override (the default, unchanged output); `editable` enables double-click
1475
1485
  editing, `editValue` supplies the editor value, and `editType` selects `text` or `number`
1486
+ `resizable` adds a pointer-driven `[part='resize-handle']` and emits `lyra-column-resize` with the
1487
+ live width in CSS pixels; an explicit pixel `minWidth` is respected.
1476
1488
  - `columnsHidden: boolean = false` (attribute `columns-hidden`, reflected) — computed/read-only: true
1477
1489
  when a `priority` column is *actually* hidden right now by the `@container` breakpoints above, or
1478
1490
  `showAllColumns` force-visible mode is currently active. Measured via a `ResizeObserver` on
@@ -1538,6 +1550,19 @@ and loading chrome are built in while remaining controlled at the public API bou
1538
1550
  button's label once they've been revealed)
1539
1551
  - `showAllColumns: boolean = false` (attribute `show-all-columns`, reflected) — forces responsive
1540
1552
  priority columns visible and is updated by the built-in reveal button
1553
+ - `heatTintScale?: { min?: number; max?: number }` (attribute: false) — overrides the auto-derived
1554
+ heat-tint domain (min/max of every `heatValue` result across every currently-rendered row —
1555
+ post-sort, pre-pagination, the same rows `footer(rows)` already sees). Unset (the default) computes
1556
+ the domain automatically from the data, spanning every `heatValue`-defining column together — a
1557
+ single shared scale across the whole grid, not one scale per column
1558
+ - `rowTotal?: (row: T) => unknown` (attribute: false) — renders a trailing `<td>`
1559
+ (`[part='row-total-cell']`) on every body row holding this row's total. Same "consumer
1560
+ computes/renders, table only positions" contract as the existing per-column `footer(rows)` — does
1561
+ not assume addition, so a non-sum aggregate works identically. Omit for no trailing column at all
1562
+ (unchanged output)
1563
+ - `grandTotal?: (rows: T[]) => unknown` (attribute: false) — renders the bottom-right cell (row-total
1564
+ column × footer row). Only rendered when both `rowTotal` is set **and** at least one column defines
1565
+ `footer` — otherwise there is no footer row for it to occupy, and this renders nothing
1541
1566
 
1542
1567
  **Events:** `lyra-sort` (`detail: { key }`, fired on sortable-header activation), `lyra-row-click`
1543
1568
  (`detail: { row }`), `lyra-load-more` (fired on the "load more" button), `lyra-columns-hidden-change`
@@ -1547,19 +1572,26 @@ and loading chrome are built in while remaining controlled at the public API bou
1547
1572
  `lyra-selection-change` (`detail: { keys }`) when selection is enabled, `lyra-filter-change`
1548
1573
  (`detail: { text }`), and `lyra-page-change` (`detail: { page }`) from the controlled
1549
1574
  filter/pagination surfaces, and `lyra-cell-edit` (`detail: { row, key, value }`) for editable
1550
- columns
1575
+ columns, and `lyra-column-resize` (`detail: { key, width }`) on every resize drag step
1551
1576
 
1552
1577
  **Slots:** none — content comes entirely from `columns`/`rows`.
1553
1578
 
1554
1579
  **CSS parts:** `base`, `table`, `head`, `header-cell`, `row`, `cell`, `more-button`, `sort-icon` (a
1555
1580
  chevron indicator shown on the active sortable header, rotated per `sortDir`), `reveal-columns-button`
1556
1581
  (shown only when `columnsHidden` is true), `foot` (the `<tfoot>`, only rendered when at least one
1557
- column defines `footer`), `footer-row`, `footer-cell`, `expand-toggle-cell`, `row-expand-toggle`,
1582
+ column defines `footer`), `footer-row`, `footer-cell`, `row-total-cell` (each body row's trailing
1583
+ `<td>` holding `rowTotal(row)`, rendered only when `rowTotal` is set — the corresponding footer-row
1584
+ cell, holding `grandTotal`, is a `footer-cell` instead, matching every other footer cell),
1585
+ `expand-toggle-cell`, `row-expand-toggle`,
1558
1586
  `row-expand-icon`, `expanded-row`, `expanded-cell`, `filter-label`, `filter`, `loading`, and
1559
- `pagination`, `cell-editor`, `group-row`, and `group-cell`
1587
+ `pagination`, `cell-editor`, `group-row`, `group-cell`, and `resize-handle`
1560
1588
 
1561
1589
  **Themeable custom properties:** `--lyra-table-max-height` (default `none`; controls the scrollable
1562
- body's `max-block-size`).
1590
+ body's `max-block-size`). `--lyra-table-heat-tint-lo` (default `var(--lyra-color-brand-quiet)`) and
1591
+ `--lyra-table-heat-tint-hi` (default `var(--lyra-color-brand)`) — the `color-mix()` ramp endpoints
1592
+ for heat-tint mode's per-cell background, consulted only on columns/rows that define `heatValue`;
1593
+ `--lyra-table-resize-min-width` (default `var(--lyra-size-3rem)`) and
1594
+ `--lyra-table-resize-handle-opacity` (default `0.12`) control resizable-column behavior.
1563
1595
 
1564
1596
  **Optional peer deps:** none.
1565
1597
 
@@ -2507,16 +2539,95 @@ same color as `--lyra-heatmap-focus-ring-color`).
2507
2539
 
2508
2540
  ---
2509
2541
 
2542
+ ## `lyra-sequence-strip`
2543
+
2544
+ A compact, one-thin-cell-per-item strip visualizing a sequence of categorical states, with an
2545
+ optional secondary per-cell marker. Pure CSS/flex — no chart.js, no SVG, no canvas — sized/named
2546
+ consistently with the sparkline/heatmap family, but a glanceable *aggregate* visualization
2547
+ (`role="img"`, one summarizing `aria-label`) rather than a `role="list"` of separately-operable
2548
+ items: there is no per-cell keyboard focus and no per-cell click event, matching `<lyra-sparkline>`'s
2549
+ accessibility model rather than `<lyra-heatmap>`'s heavier canvas-plus-keyboard-roving one. Hovering a
2550
+ cell (pointer only) shows `[part="tooltip"]` with that item's label.
2551
+
2552
+ **Properties:**
2553
+ - `items: SequenceStripItem[] = []` (attribute: false) — `{ id, category, marker?, label? }`;
2554
+ `marker` renders a small bottom marker on that cell independent of the category color (e.g. a
2555
+ subagent-dispatched turn); `label` is per-item hover-tooltip text, falling back to the matching
2556
+ category's own `label` (or its `key`) when unset — not read by the auto-generated `aria-label`,
2557
+ which summarizes by category/count only
2558
+ - `categories: SequenceStripCategory[] = []` (attribute: false) — `{ key, color, label? }`; `color`
2559
+ is the cell background for every item whose `category` matches `key` (an item whose `category`
2560
+ matches no entry renders `transparent`); `label` is used in the auto-generated `aria-label` summary
2561
+ and as the hover-tooltip fallback text, falling back to `key` itself when unset
2562
+ - `orientation: 'horizontal' = 'horizontal'` (reflected) — only `'horizontal'` is supported today;
2563
+ vertical is plausible future scope, not built speculatively without a motivating case
2564
+ - `accessibleLabel?: string` (attribute `accessible-label`) — overrides the auto-generated
2565
+ `aria-label` (a per-category "label: count" summary, e.g. `"Text: 2, Tool: 1"`). Unset computes the
2566
+ summary from `items`/`categories`
2567
+
2568
+ **Events:** none.
2569
+
2570
+ **Slots:** none.
2571
+
2572
+ **CSS parts:** `base` (the root strip, `role="img"`), `cell` (each item's cell, background-colored
2573
+ by its category), `marker` (the small bottom marker on a cell whose item sets `marker: true`),
2574
+ `tooltip` (the hover tooltip showing the hovered item's label, hidden until a cell is hovered).
2575
+
2576
+ **Themeable custom properties:** `--lyra-sequence-strip-height` (default `1.5rem` — the strip's
2577
+ block-size) and `--lyra-sequence-strip-marker-color` (default `var(--lyra-color-text)` — the
2578
+ `[part="marker"]` fill); the tooltip also consumes shared tokens `--lyra-color-surface`,
2579
+ `--lyra-color-text`, `--lyra-font-size-xs`, `--lyra-radius`, and `--lyra-shadow`.
2580
+
2581
+ **Optional peer deps:** none.
2582
+
2583
+ ```html
2584
+ <lyra-sequence-strip></lyra-sequence-strip>
2585
+ <script>
2586
+ const strip = document.querySelector('lyra-sequence-strip');
2587
+ strip.categories = [
2588
+ { key: 'text', color: '#4f46e5', label: 'Text' },
2589
+ { key: 'tool', color: '#16a34a', label: 'Tool' },
2590
+ ];
2591
+ strip.items = [
2592
+ { id: '1', category: 'text', label: 'Turn 1: text' },
2593
+ { id: '2', category: 'tool', marker: true, label: 'Turn 2: tool call' },
2594
+ { id: '3', category: 'text', label: 'Turn 3: text' },
2595
+ ];
2596
+ </script>
2597
+ ```
2598
+
2599
+ **Known gotchas:**
2600
+ - there is no `lyra-cell-click`/keyboard-interaction model at all — unlike `lyra-heatmap`'s
2601
+ canvas cells, a strip cell is purely a hover target; build a click handler outside this component
2602
+ (e.g. on a wrapping element) if per-item activation is needed.
2603
+ - an `items` entry whose `category` has no matching `categories` entry still renders its own cell
2604
+ (background `transparent`) rather than being dropped, so a strip stays the same length as `items`
2605
+ regardless of `categories` coverage.
2606
+
2607
+ ---
2608
+
2510
2609
  ## `lyra-graph`
2511
2610
 
2512
2611
  A force-directed node-link diagram with pan/zoom/drag, built on `d3-force`.
2513
2612
 
2514
2613
  **Properties:**
2515
2614
  - `nodes: GraphNode[] = []` (attribute: false) — `GraphNode { id: string; label?: string;
2516
- accessibleLabel?: string; description?: string; radius?: number; color?: string }`;
2615
+ accessibleLabel?: string; description?: string; radius?: number; color?: string; type?: string }`;
2517
2616
  `accessibleLabel` supplies richer spoken text than the visible label, while `description` renders
2518
2617
  as native SVG `<title>` tooltip text. `radius` is clamped to `[6, 24]` (an unset/non-finite value
2519
- falls back to the midpoint, `15`) so a node can never render invisibly small or absurdly large
2618
+ falls back to the midpoint, `15`) so a node can never render invisibly small or absurdly large.
2619
+ `type` is a key into `nodeTypes` (matched by `GraphNodeType.id`); unknown/absent renders as an
2620
+ untyped default circle with the token fill, but an unmatched `type` still participates in
2621
+ `hiddenTypes` filtering by its raw string value
2622
+ - `nodeTypes: GraphNodeType[] = []` (attribute: false) — `GraphNodeType { id: string; label: string;
2623
+ color?: string; shape?: 'circle' | 'square' | 'diamond' }`, one entry per `GraphNode.type` value:
2624
+ `label` feeds the spoken "typed node" summary, and `shape`/`color` drive rendering per node.
2625
+ Per-node fill resolution precedence is `GraphNode.color` (most specific) > the matched
2626
+ `GraphNodeType.color` > an ordered categorical fallback palette assigned by the type's index in
2627
+ `nodeTypes` (`--lyra-graph-cat-1` through `-8`, wrapping every 8 entries) > the untyped
2628
+ `--lyra-node-fill` default; both data-driven color sources are sanitized the same way as
2629
+ `GraphNode.color` itself. A typed node with no matching `nodeTypes` entry renders as a plain
2630
+ circle with the untyped default fill
2520
2631
  - `links: GraphLink[] = []` (attribute: false) — `GraphLink { id?: string; source: string; target:
2521
2632
  string; width?: number; label?: string; accessibleLabel?: string; description?: string; directed?:
2522
2633
  boolean; color?: string; dash?: number[] }` (source/target are node ids). `directed` adds an
@@ -2541,19 +2652,65 @@ A force-directed node-link diagram with pan/zoom/drag, built on `d3-force`.
2541
2652
  (keyed by node **id**, not array index/order) instead of `forceSimulation()`'s own random start,
2542
2653
  and settles the simulation synchronously instead of animating the settle (same effect
2543
2654
  `prefers-reduced-motion` has, see gotchas)
2544
-
2545
- **Events:** `lyra-node-click` (`detail: { id }`), `lyra-link-click` (`detail: { source, target,
2546
- id? }`; the optional `id` is the stable `GraphLink.id` supplied by the caller)
2655
+ - `showEdgeLabels: boolean = false` (attribute `show-edge-labels`) — draws each resolved
2656
+ (non-dangling) link's `label` as visible SVG text (`[part="link-label"]`) at the segment midpoint.
2657
+ Off by default: `GraphLink.label` stays spoken/tooltip-only, matching pre-existing behavior, unless
2658
+ this is set
2659
+ - `edgeLabelMinZoom: number = 0.6` (attribute `edge-label-min-zoom`) — below this zoom scale, every
2660
+ drawn edge label is hidden (toggled via a `data-edge-labels-hidden` attribute on the zoomed `<g>`,
2661
+ not a Lit re-render, so it tracks pan/zoom smoothly). Ignored entirely when `showEdgeLabels` is
2662
+ `false`
2663
+ - `layout: 'force' | 'layered' = 'force'` — `'force'` runs the `d3-force` simulation described
2664
+ throughout this section, unchanged. `'layered'` swaps in a deterministic Sugiyama-lite layered
2665
+ layout instead (longest-path layering, barycenter crossing reduction, cycle-safe — back edges are
2666
+ reversed only for layering, never mutating caller data): positions are computed synchronously
2667
+ with no settle animation, sized from each node's own radius and spaced by `linkDistance` (the
2668
+ layer gap) and a fixed 12px in-layer gap. Node drag is disabled in this mode (dragging would fight
2669
+ a computed layout) and `chargeStrength` becomes a documented no-op; pan/zoom, keyboard roving,
2670
+ `focusNode()`/`fit()`, hulls, edge labels, and `hiddenTypes` filtering all work identically to
2671
+ force mode. Switching `layout` at runtime repositions every node without a tween. The layering
2672
+ algorithm itself lives in the standalone, dependency-free `layeredLayout()` export
2673
+ (`@aceshooting/lyra-ui/internal/layered-layout`), reusable by any other layered-diagram consumer
2674
+ - `renderer: 'svg' | 'canvas' = 'svg'` — `'canvas'` swaps the per-node/per-link SVG DOM for a single
2675
+ DPR-aware `<canvas>`; every event/method/property behaves identically to `'svg'`, with hit-testing
2676
+ resolved via an offscreen color-picking canvas instead of DOM event targets. Trade-offs: no
2677
+ `::part(node)`/`::part(link)` styling (pixels, not elements — theme via cssprops instead), no
2678
+ native SVG `<title>` tooltip (replaced by `part="tooltip"`), and a drawn focus ring instead of a
2679
+ CSS one. Keyboard roving/announcements are preserved through an offscreen `part="cursor-item"`
2680
+ button per node/link/hull.
2681
+
2682
+ **Methods:** `focusNode(id, options?: { zoom? })` and `fit(options?: { padding?: number })` control the
2683
+ camera; `getNodePosition(id)` returns the current `{ x, y }` in graph-local drawing coordinates, or
2684
+ `undefined` when the id is not currently simulated.
2685
+
2686
+ **Events:** `lyra-node-click` (`detail: { id, x, y }`, where `x` and `y` are the clicked node's current
2687
+ local drawing coordinates), `lyra-link-click` (`detail: { source, target,
2688
+ id? }`; the optional `id` is the stable `GraphLink.id` supplied by the caller), `lyra-node-enter`/
2689
+ `lyra-node-leave` (`detail: { id }`, hover start/end, suppressed while dragging/panning),
2690
+ `lyra-link-enter`/`lyra-link-leave` (`detail: { source, target, id? }`, same hover contract),
2691
+ `lyra-node-expand` (`detail: { id }`, a node was double-activated — native `dblclick`, or two
2692
+ Enter/Space activations within 500ms — regardless of `GraphNode.expandable`), `lyra-community-click`
2693
+ (`detail: { id }`, a hull was activated)
2547
2694
 
2548
2695
  **Slots:** none.
2549
2696
 
2550
2697
  **CSS parts:** `base`, `svg`, `node`, `link`, `arrowhead` (the marker path shared by directed links),
2551
- `label`, `live-region`, `data-list`, `empty`
2698
+ `label`, `link-label` (a drawn edge label, only rendered when `showEdgeLabels` is set),
2699
+ `expand-indicator` (the "+" badge on a node with `expandable: true`), `focus-halo` (the persistent
2700
+ ring tracking `focusId`'s node), `hull` (a community hull), `community-label`,
2701
+ `live-region`, `data-list`, `empty`, `canvas`/`tooltip`/`cursor-items`/`cursor-item`
2702
+ (`renderer="canvas"` only — the drawing surface, its hover tooltip replacing the SVG `<title>`, and
2703
+ the offscreen keyboard-roving items)
2552
2704
 
2553
2705
  **Themeable custom properties:** `--lyra-node-fill` (set inline per-node from `GraphNode.color`,
2554
2706
  falls back to `--lyra-color-brand`) and `--lyra-link-color` (set inline per-link from
2555
2707
  `GraphLink.color`, falling back to `--lyra-color-border`); also uses `--lyra-color-text` +
2556
2708
  `--lyra-font` (label text), `--lyra-focus-ring-*` (node/link `:focus-visible` outline).
2709
+ `--lyra-graph-cat-1` through `-8` — the ordered categorical fallback palette for a typed node with
2710
+ no `GraphNodeType.color`, assigned by the type's index in `nodeTypes` (wraps every 8 entries);
2711
+ declared centrally in `tokens.styles.ts` so this stays the same default across components.
2712
+ `--lyra-graph-edge-label-halo` (default `var(--lyra-color-surface)`) — the legibility halo painted
2713
+ behind a drawn `[part="link-label"]` (via `paint-order: stroke`).
2557
2714
 
2558
2715
  **Optional peer deps:** `d3-force`, `d3-drag`, `d3-zoom`, `d3-selection` (all four required
2559
2716
  together; lazy-`import()`ed once per page, `console.warn` once and renders empty if missing —
@@ -2616,6 +2773,32 @@ install with `pnpm add d3-force d3-drag d3-zoom d3-selection`).
2616
2773
  - the `<svg part="svg">` now carries `role="group"` and an `aria-label` summarizing the node/link
2617
2774
  counts (e.g. "Node-link diagram with 5 nodes and 4 links"), and node `<text part="label">`s are
2618
2775
  `aria-hidden="true"` (their content is already covered by each node's own `aria-label`).
2776
+ - `nodeTypes` and `showEdgeLabels` are live-reactive post-mount: either changing re-scans/rebinds the
2777
+ cached per-node and per-link DOM element arrays, alongside the existing `simNodes`/`simLinks`
2778
+ structural-change trigger — no need to also touch `nodes`/`links` to see a type/shape/color or
2779
+ edge-label change take effect.
2780
+ - when `showEdgeLabels` is `false` (the default), a resolved link renders as a bare `<line
2781
+ part="link">` with no extra wrapping element, so existing consumers who never set it see
2782
+ byte-for-byte identical link DOM; setting it wraps each link's `<line>` and its
2783
+ `[part="link-label"]` `<text>` together. `edgeLabelMinZoom`'s hide/show gate is applied once at
2784
+ mount (against d3-zoom's known identity transform) as well as on every subsequent pan/zoom, so
2785
+ labels never wrongly start visible before the first user gesture.
2786
+
2787
+ **Selection & focus:** `selectionMode: 'none' | 'single' | 'multiple' = 'none'` (attribute
2788
+ `selection-mode`) gates click/keyboard selection; the component never mutates
2789
+ `selectedNodeIds: string[] = []` / `selectedLinkIds: string[] = []` (both attribute: false) itself,
2790
+ only emits `lyra-selection-change` (`detail: { nodeIds, linkIds }`) — the host assigns them back,
2791
+ mirroring `lyra-heatmap`'s `selectedCell` contract. `dimmedNodeIds: string[] = []` / `dimmedLinkIds:
2792
+ string[] = []` (both attribute: false) are the same controlled shape for dimming instead of
2793
+ selecting — the component never assigns either itself, only renders `data-dimmed` on the matching
2794
+ `[part="node"]`/`[part="link"]` (themeable via `--lyra-graph-dimmed-opacity`); a host typically
2795
+ computes the set from a `lyra-node-enter`/`lyra-link-enter` hover (the complement of the hovered
2796
+ id's neighbor set) and assigns it back. Empty (the default) renders every node/link at full
2797
+ opacity, unchanged from today. `communities: GraphCommunity[] = []` (attribute:
2798
+ false) draws one translucent convex-hull blob per entry behind links/nodes. `focusId: string | null =
2799
+ null` (attribute `focus-id`) tracks a persistent focus ring (`[part="focus-halo"]`) around one node;
2800
+ `focusNode(id, options?)` and `fit(options?)` are the imperative camera-tween counterparts (pan/zoom
2801
+ to a node, or to fit the whole graph), both resolving once the tween settles.
2619
2802
 
2620
2803
  ---
2621
2804
 
@@ -2701,42 +2884,852 @@ through `lyra-tree`'s light DOM.
2701
2884
  `aria-hidden="true"`; `content` groups the primary label and optional wrapping secondary
2702
2885
  description while preserving one interactive treeitem per row.
2703
2886
 
2704
- **Themeable custom properties:** `--lyra-tree-depth` (internal, set inline per row for
2705
- indentation), plus the shared tokens listed above.
2887
+ **Themeable custom properties:** `--lyra-tree-depth` (internal, set inline per row for
2888
+ indentation), plus the shared tokens listed above.
2889
+
2890
+ **Optional peer deps:** none.
2891
+
2892
+ ```html
2893
+ <lyra-tree></lyra-tree>
2894
+ <script>
2895
+ document.querySelector('lyra-tree').data = [
2896
+ {
2897
+ id: '1',
2898
+ label: 'Root',
2899
+ description: 'Two child documents',
2900
+ accessibleLabel: 'Root, two child documents',
2901
+ icon: document.createTextNode('◇'),
2902
+ children: [{ id: '1a', label: 'Child A' }, { id: '1b', label: 'Child B', badge: 3 }],
2903
+ },
2904
+ ];
2905
+ </script>
2906
+ ```
2907
+
2908
+ **Known gotchas:**
2909
+ - all four previously-known ARIA gaps in this pair are fixed: the treeitem row is now genuinely
2910
+ keyboard-operable with a roving tabindex and full arrow-key navigation (not just the expand/collapse
2911
+ button); the expanded-children `role="group"` is now a real DOM descendant of its `role="treeitem"`
2912
+ host rather than a shadow-DOM sibling; by-id reconciliation (preserving `expanded` state across
2913
+ data reassignment) now applies at every depth via a keyed `repeat()`, not just depth 0; and
2914
+ `role="tree"` now has an accessible name via the new `label` property.
2915
+ - `lyra-tree`'s `getUpdateComplete()` cascades into every currently-known descendant
2916
+ `<lyra-tree-node>`'s own `updateComplete` (see `update-cascade.ts`) so that code awaiting the
2917
+ tree's `updateComplete` (e.g. after `focusNode()`) doesn't run before an arbitrarily-nested node has
2918
+ actually finished rendering its pushed-down `activeId`/`tabIndex` — one more pending update per
2919
+ depth level, otherwise.
2920
+ - row enrichment is intentionally structured rather than an unrestricted renderer: use `icon`,
2921
+ `label`, `description`, `badge`, and `accessibleLabel`. This keeps the host as the single
2922
+ `role="treeitem"` interaction target and preserves the APG keyboard model.
2923
+
2924
+ ---
2925
+
2926
+ # Flow canvas
2927
+
2928
+ ## `lyra-flow-canvas`
2929
+
2930
+ A pannable/zoomable DAG workflow canvas: positions HTML node cards, draws SVG edges between their
2931
+ handles, runs a shared layered auto-layout for unpositioned nodes, and owns all selection/drag/
2932
+ connect interaction as controlled events. Readonly (viewer) by default; opt into editor gestures
2933
+ individually via `nodes-draggable`, `connectable`, `droppable`. Never mutates `nodes` or `edges`
2934
+ itself — every edit intent is an event the host applies, mirroring `lyra-stepper`/`lyra-table`'s
2935
+ controlled-component contract.
2936
+
2937
+ **Properties:**
2938
+ - `nodes: FlowNode[] = []` (attribute: false) — `FlowNode { id: string; type?: string; position?: {
2939
+ x, y }; data?: Record<string, unknown>; accessibleLabel?: string; inputs?: FlowHandle[]; outputs?:
2940
+ FlowHandle[] }`; a node with no `position` is placed by the layered auto-layout, and `data.label`/
2941
+ `data.description` feed the default `<lyra-flow-node>` card when no matching light-DOM child exists
2942
+ - `edges: FlowEdge[] = []` (attribute: false) — `FlowEdge { id: string; source: string; target:
2943
+ string; sourceHandle?: string; targetHandle?: string; label?: string; tone?: 'accent' | 'success' |
2944
+ 'warning' | 'danger' | 'neutral' }` (source/target are node ids; `label` draws at the edge midpoint,
2945
+ unlike `lyra-graph`'s spoken-only `GraphLink.label`)
2946
+ - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — downstream layout/handle axis
2947
+ - `nodesDraggable: boolean = false` (attribute `nodes-draggable`)
2948
+ - `connectable: boolean = false`
2949
+ - `droppable: boolean = false` — accepts drops carrying the `FLOW_PALETTE_MIME_TYPE` payload a
2950
+ `lyra-node-palette` drag sets, emitting `lyra-node-add`
2951
+ - `locked: boolean = false` (reflected) — freezes pan/zoom/drag/connect without touching the other
2952
+ gesture flags
2953
+ - `selectedNodeIds: string[] = []`, `selectedEdgeIds: string[] = []` (attribute: false) — controlled;
2954
+ the host assigns these back from `lyra-selection-change`
2955
+ - `minZoom: number = 0.25` (attribute `min-zoom`), `maxZoom: number = 2` (attribute `max-zoom`)
2956
+ - `grid: number = 8` — snap step in content px for drags/nudges/drop positions (`0` disables
2957
+ snapping); also the dotted background's base spacing
2958
+ - `layerGap: number = 64` (attribute `layer-gap`), `nodeGap: number = 24` (attribute `node-gap`) —
2959
+ auto-layout layer/sibling spacing
2960
+ - `decorations: FlowRunDecorations | null = null` (attribute: false) — `Record<nodeOrEdgeId,
2961
+ FlowRunDecoration>`, `FlowRunDecoration { status: 'pending'|'running'|'success'|'error'|'denied';
2962
+ progress?: number; durationMs?: number; detail?: string }`; pushed onto adopted `lyra-flow-node`
2963
+ cards, typically supplied via a `lyra-flow-run-overlay`
2964
+ - `accessibleLabel: string | null = null` (attribute `aria-label`)
2965
+ - `viewport` (read-only getter) — `{ x, y, zoom }`, the current pan/zoom state
2966
+
2967
+ **Methods:** `setViewport({ x, y, zoom })`, `zoomIn()`, `zoomOut()`, `resetZoom()`,
2968
+ `fit(options?: { padding?: number })` (frames every node), `focusNode(id, options?: { zoom? })`
2969
+ (pans/zooms to one node and moves roving focus onto it), `toContentPoint(clientX, clientY)` (maps a
2970
+ pointer position to content coordinates, RTL-aware), `registerCompanion(cb: (snapshot:
2971
+ FlowStructureSnapshot) => void): () => void` — the subscription `lyra-flow-minimap` uses to read
2972
+ live node/edge/viewport geometry without this canvas ever importing the minimap.
2973
+
2974
+ **Events:** `lyra-node-click` (`detail: { id }`), `lyra-edge-click` (`detail: { id, source, target
2975
+ }`), `lyra-selection-change` (`detail: { nodeIds, edgeIds }`), `lyra-node-move` (`detail: { id,
2976
+ position, previous }`), `lyra-connect` (`detail: { source, target, sourceHandle, targetHandle }`),
2977
+ `lyra-node-add` (`detail: { type, position }`, from a palette drop), `lyra-selection-delete`
2978
+ (`detail: { nodeIds, edgeIds }`), `lyra-viewport-change` (`detail: { x, y, zoom }`),
2979
+ `lyra-layout-change` (`detail: { positions }`, fired after an auto-layout pass places previously
2980
+ unpositioned nodes).
2981
+
2982
+ **Slots:** default (`lyra-flow-node` children adopted by `node-id`; a non-matching child is ignored
2983
+ with a console warning), `top-start`, `top-end` (floating corner overlays), `bottom-start` (e.g.
2984
+ `lyra-flow-controls`), `bottom-end` (e.g. `lyra-flow-minimap`).
2985
+
2986
+ **CSS parts:** `base`, `viewport`, `background`, `edges`, `edge`, `edge-label`, `arrowhead`, `stub`
2987
+ (a dangling-edge stub line), `connection-line` (in-progress connect gesture), `node`, `empty`,
2988
+ `live-region`, `edge-list` (a visually hidden list of every edge).
2989
+
2990
+ **Themeable custom properties:** `--lyra-flow-canvas-grid-size` (default `8px`, dotted background
2991
+ spacing), `--lyra-flow-canvas-march-duration` (default `var(--lyra-transition-ambient)`, running-edge
2992
+ march animation duration).
2993
+
2994
+ **Optional peer deps:** none.
2995
+
2996
+ ```html
2997
+ <lyra-flow-canvas id="canvas" nodes-draggable connectable droppable style="height:480px"></lyra-flow-canvas>
2998
+ <lyra-flow-controls slot="bottom-start" for="canvas"></lyra-flow-controls>
2999
+ <lyra-flow-minimap slot="bottom-end" for="canvas"></lyra-flow-minimap>
3000
+ <script>
3001
+ const canvas = document.getElementById('canvas');
3002
+ canvas.nodes = [
3003
+ { id: 'a', data: { label: 'Fetch' } },
3004
+ { id: 'b', data: { label: 'Transform' } },
3005
+ ];
3006
+ canvas.edges = [{ id: 'a-b', source: 'a', target: 'b' }];
3007
+ canvas.addEventListener('lyra-node-move', (e) => {
3008
+ canvas.nodes = canvas.nodes.map((n) => (n.id === e.detail.id ? { ...n, position: e.detail.position } : n));
3009
+ });
3010
+ </script>
3011
+ ```
3012
+
3013
+ **Known gotchas:**
3014
+ - Fully controlled: `nodes`/`edges`/`selectedNodeIds`/`selectedEdgeIds` are never mutated
3015
+ internally — `lyra-node-move`, `lyra-selection-change`, `lyra-connect`, `lyra-node-add`, and
3016
+ `lyra-selection-delete` are all requests the host applies back, same contract as `lyra-table`.
3017
+ - Auto-layout (via the dependency-free `layeredLayout()` util) only ever positions nodes that are
3018
+ missing an explicit `position`; a node the host has already positioned is left exactly where it is
3019
+ and used as a fixed anchor for the rest of the layout pass.
3020
+ - `droppable` only accepts drags carrying the exact `FLOW_PALETTE_MIME_TYPE` MIME type a
3021
+ `lyra-node-palette` drag sets — the two components can never disagree on the payload shape because
3022
+ they share one exported constant.
3023
+ - Pan/drag/zoom track the pointer's physical direction; under an RTL ancestor the pan and node-drag
3024
+ deltas are mirrored so content still visually follows the cursor, matching every other
3025
+ RTL-mirrored surface in this library.
3026
+
3027
+ ---
3028
+
3029
+ ## `lyra-flow-node`
3030
+
3031
+ The card a workflow node renders as: header/body/toolbar chrome, tool-lifecycle status tones, and
3032
+ the named connection-handle elements edges anchor to. Used as `lyra-flow-canvas`'s default card and
3033
+ as a slotted override; also renders standalone (palette previews, docs). Purely presentational —
3034
+ activation, selection, movement, and connection are all `lyra-flow-canvas` events; this component
3035
+ owns none of that.
3036
+
3037
+ **Properties:**
3038
+ - `nodeId: string = ''` (attribute `node-id`)
3039
+ - `heading: string = ''`
3040
+ - `status: 'pending' | 'running' | 'success' | 'error' | 'denied' | null = null` (reflected)
3041
+ - `progress: number | null = null` — renders a determinate `[part="progress"]` bar when set
3042
+ - `statusDetail: string = ''` (attribute `status-detail`) — appended to the status line
3043
+ - `durationMs: number | null = null` (attribute `duration-ms`) — formatted into the status line
3044
+ - `selected: boolean = false` (reflected)
3045
+ - `inputs: FlowHandle[] = [{ id: 'in' }]`, `outputs: FlowHandle[] = [{ id: 'out' }]` (attribute:
3046
+ false) — `FlowHandle { id: string; label?: string }`
3047
+ - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — which physical edge handles
3048
+ render on; mirrors the adopting canvas's own `orientation`
3049
+
3050
+ **Events:** none — purely presentational, activation/drag/connect all live on `lyra-flow-canvas`.
3051
+
3052
+ **Slots:** default (body content), `icon` (leading header glyph), `header` (replaces the built-in
3053
+ heading row entirely), `toolbar` (action row at the block-end edge).
3054
+
3055
+ **CSS parts:** `base`, `header`, `icon`, `heading`, `status` (never color-only — always paired with
3056
+ text), `progress`, `body`, `toolbar`, `handle` (every handle dot), `handle-input`, `handle-output`.
3057
+
3058
+ **Themeable custom properties:** `--lyra-flow-node-min-inline-size` (default `11rem`).
3059
+
3060
+ **Optional peer deps:** none.
3061
+
3062
+ ```html
3063
+ <lyra-flow-node node-id="a" heading="Fetch" status="running" progress="40"></lyra-flow-node>
3064
+ ```
3065
+
3066
+ **Known gotchas:**
3067
+ - A running node's card pulses (`?data-pulse`) unless `prefers-reduced-motion` is set — the same
3068
+ reduced-motion exception every animated surface in this library follows.
3069
+ - `status` drives a status chip with a localized label plus `statusDetail`/`durationMs`, never a
3070
+ color-only indicator.
3071
+
3072
+ ---
3073
+
3074
+ ## `lyra-flow-minimap`
3075
+
3076
+ A corner overview map of a `lyra-flow-canvas`: scaled node rectangles plus a draggable viewport
3077
+ rectangle, for orientation and fast navigation on canvases larger than the screen. Draws no edges
3078
+ (nodes only, matching the React Flow/n8n minimap convention) and never reads `nodes` itself —
3079
+ geometry always comes from the canvas's `registerCompanion()` snapshots, so the two can never
3080
+ disagree.
3081
+
3082
+ **Properties:**
3083
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; when empty, the nearest ancestor canvas
3084
+ is used (the slotted-into-a-corner-slot case, the primary wiring)
3085
+ - `label: string = ''` — accessible name for the map region; falls back to a host `aria-label`, then
3086
+ a localized default
3087
+
3088
+ **Events:** none.
3089
+
3090
+ **Slots:** none.
3091
+
3092
+ **CSS parts:** `base`, `map` (the scaled SVG), `node` (one rect per node), `viewport` (the
3093
+ draggable, focusable view rectangle).
3094
+
3095
+ **Themeable custom properties:** `--lyra-flow-minimap-inline-size` (default `12rem`),
3096
+ `--lyra-flow-minimap-block-size` (default `8rem`).
3097
+
3098
+ **Optional peer deps:** none.
3099
+
3100
+ ```html
3101
+ <lyra-flow-canvas id="canvas" style="height:480px">
3102
+ <lyra-flow-minimap slot="bottom-end" for="canvas"></lyra-flow-minimap>
3103
+ </lyra-flow-canvas>
3104
+ ```
3105
+
3106
+ **Known gotchas:**
3107
+ - Never resolves `nodes`/`edges` on its own — it subscribes to `registerCompanion()` and repaints
3108
+ from whatever snapshot the canvas last pushed, so it can only ever show what the canvas itself
3109
+ currently renders.
3110
+ - Dragging the viewport rectangle calls the canvas's `setViewport()` directly; there's no separate
3111
+ event to wire up.
3112
+
3113
+ ---
3114
+
3115
+ ## `lyra-flow-controls`
3116
+
3117
+ The canvas's button cluster: zoom in/out, fit, and interaction lock, so every flow surface ships the
3118
+ same affordances without hosts rebuilding them. Manipulates only view state, never `nodes`/`edges` —
3119
+ no editing commands live here.
3120
+
3121
+ **Properties:**
3122
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; empty resolves to the nearest ancestor
3123
+ - `orientation: 'vertical' | 'horizontal' = 'vertical'` (reflected) — button-cluster layout axis
3124
+ - `hideLock: boolean = false` (attribute `hide-lock`) — omits the lock/unlock toggle button
3125
+
3126
+ **Events:** none dispatched directly — each button calls the resolved canvas's own `zoomIn()`/
3127
+ `zoomOut()`/`fit()`, or toggles its `locked` property.
3128
+
3129
+ **Slots:** default — extra host buttons appended to the cluster, styled by the same group.
3130
+
3131
+ **CSS parts:** `base` (the `role="group"` wrapper), `zoom-in`, `zoom-out`, `fit`, `lock` (omitted
3132
+ when `hideLock`).
3133
+
3134
+ **Themeable custom properties:** shared tokens only.
3135
+
3136
+ **Optional peer deps:** none.
3137
+
3138
+ ```html
3139
+ <lyra-flow-canvas id="canvas" style="height:480px">
3140
+ <lyra-flow-controls slot="bottom-start" for="canvas"></lyra-flow-controls>
3141
+ </lyra-flow-canvas>
3142
+ ```
3143
+
3144
+ **Known gotchas:**
3145
+ - `for` resolution is identical to `lyra-flow-minimap`/`lyra-flow-run-overlay`: an explicit id, else
3146
+ the nearest ancestor canvas — none of the three companions import `LyraFlowCanvas` as a value, only
3147
+ its types, so registration order between them and the canvas never matters.
3148
+
3149
+ ---
3150
+
3151
+ ## `lyra-node-palette`
3152
+
3153
+ The searchable, categorized node library for workflow editors: drag an item onto a canvas, or place
3154
+ it by keyboard. Never creates nodes or touches a canvas's data itself — the drop/place handshake ends
3155
+ at `lyra-node-add`/`lyra-palette-place`; the host mutates `nodes`. Fully decoupled from
3156
+ `lyra-flow-canvas` (no `for` resolution, unlike the other three companions) — it only needs to agree
3157
+ with a `droppable` canvas on the `FLOW_PALETTE_MIME_TYPE` drag payload shape.
3158
+
3159
+ **Properties:**
3160
+ - `items: PaletteItem[] = []` (attribute: false) — `PaletteItem { type: string; label: string;
3161
+ description?: string; category?: string; keywords?: string[]; icon?: unknown; disabled?: boolean }`;
3162
+ `type` is the `FlowNode.type` a placement/drop creates, `category` groups items under
3163
+ first-appearance-ordered headings, `disabled` renders an item visible but not draggable/placeable
3164
+ - `label: string = ''` — accessible name for the search field/listbox
3165
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — overrides the listbox's
3166
+ computed accessible name; wins over `label` and the localized default, and attribute-reflects
3167
+ from a host-level `aria-label`
3168
+
3169
+ **Events:** `lyra-palette-place` (`detail: { type }`, a pointer click or Enter/Space — the
3170
+ click/keyboard alternative to dragging), `lyra-select` (`detail: { item }`, emitted alongside
3171
+ `lyra-palette-place` on both gestures, carrying the full item).
3172
+
3173
+ **Slots:** `header` (content above the search field, e.g. a heading or tabs), `footer` (content
3174
+ below the list).
3175
+
3176
+ **CSS parts:** `base`, `search`, `list` (the listbox), `group-header`, `item`, `item-icon`,
3177
+ `item-label`, `item-description`, `empty` (no-results message), `live-region` (result-count
3178
+ announcement).
3179
+
3180
+ **Themeable custom properties:** shared tokens only.
3181
+
3182
+ **Optional peer deps:** none.
3183
+
3184
+ ```html
3185
+ <lyra-node-palette id="palette"></lyra-node-palette>
3186
+ <lyra-flow-canvas id="canvas" droppable style="height:480px"></lyra-flow-canvas>
3187
+ <script>
3188
+ document.getElementById('palette').items = [
3189
+ { type: 'http-request', label: 'HTTP Request', category: 'Actions' },
3190
+ { type: 'transform', label: 'Transform', category: 'Actions' },
3191
+ ];
3192
+ document.getElementById('canvas').addEventListener('lyra-node-add', (e) => {
3193
+ console.log('drop payload type:', e.detail.type, e.detail.position);
3194
+ });
3195
+ </script>
3196
+ ```
3197
+
3198
+ **Known gotchas:**
3199
+ - A drag from this palette carries `FLOW_PALETTE_MIME_TYPE` as its `DataTransfer` type — only a
3200
+ `droppable` `lyra-flow-canvas` (or a host reimplementing the same MIME type) accepts it.
3201
+ - Clicking or activating an item by keyboard fires `lyra-palette-place`/`lyra-select` immediately, no
3202
+ drag required — the host decides where the new node lands (there's no pointer position to derive
3203
+ one from on a keyboard placement).
3204
+
3205
+ ---
3206
+
3207
+ ## `lyra-flow-run-overlay`
3208
+
3209
+ Execution-state presentation for a `lyra-flow-canvas`: pushes a `FlowRunDecorations` map into the
3210
+ resolved canvas (the canvas itself renders the node/edge paint) and renders a compact run-summary
3211
+ strip. Does not execute, poll, or time anything — pure pushed state; `durationMs` is host-computed.
3212
+
3213
+ **Properties:**
3214
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; empty resolves to the nearest ancestor
3215
+ - `decorations: FlowRunDecorations = {}` (attribute: false) — `Record<nodeOrEdgeId,
3216
+ FlowRunDecoration>`, pushed verbatim onto the resolved canvas's own `decorations` property
3217
+ - `hideSummary: boolean = false` (attribute `hide-summary`) — omits the "{done} of {total} steps
3218
+ complete" strip, keeping only the decoration push
3219
+ - `label: string = ''` — accessible name for the summary strip
3220
+
3221
+ **Events:** none dispatched directly.
3222
+
3223
+ **Slots:** default — extra host chrome appended to the strip (e.g. a cancel button or a usage
3224
+ badge).
3225
+
3226
+ **CSS parts:** `base`, `summary` (the "{done} of {total} steps complete" line), `count` (one per
3227
+ status present, text + tone dot, never color-only), `live-region` (step-transition announcement).
3228
+
3229
+ **Themeable custom properties:** shared tokens only.
3230
+
3231
+ **Optional peer deps:** none.
3232
+
3233
+ ```html
3234
+ <lyra-flow-canvas id="canvas" style="height:480px">
3235
+ <lyra-flow-run-overlay slot="top-start" for="canvas"></lyra-flow-run-overlay>
3236
+ </lyra-flow-canvas>
3237
+ <script>
3238
+ document.querySelector('lyra-flow-run-overlay').decorations = {
3239
+ a: { status: 'success', durationMs: 820 },
3240
+ b: { status: 'running', progress: 40 },
3241
+ };
3242
+ </script>
3243
+ ```
3244
+
3245
+ **Known gotchas:**
3246
+ - Purely a pushed-state conduit: it never starts, stops, or times a run itself — the host recomputes
3247
+ `decorations` (including `durationMs`) on whatever cadence its own execution engine ticks at.
3248
+ - `for` resolution matches `lyra-flow-minimap`/`lyra-flow-controls`.
3249
+
3250
+ ---
3251
+
3252
+ # Knowledge graph & RAG exploration
3253
+
3254
+ ## `lyra-graph-legend`
3255
+
3256
+ A node-type legend for a paired `lyra-graph`: one swatch + label + count row per node type, doubling
3257
+ as visibility filters. Never reads or writes a graph directly — the host forwards `types` in from
3258
+ `graph.nodeTypes` and `hiddenTypes` back out to `graph.hiddenTypes` on `lyra-visibility-change`, the
3259
+ same event-decoupled contract every sibling in this family follows.
3260
+
3261
+ **Properties:**
3262
+ - `types: LyraGraphLegendType[] = []` (attribute: false) — `{ id: string; label: string; color?:
3263
+ string; shape?: 'circle' | 'square' | 'diamond' }`, the exact `lyra-graph.nodeTypes` entry shape
3264
+ (declared locally, not imported, so this stays a zero-dependency component)
3265
+ - `counts?: Record<string, number>` (attribute: false) — optional per-type count shown alongside the
3266
+ label
3267
+ - `hiddenTypes: string[] = []` (attribute: false) — controlled; the host assigns this back from
3268
+ `lyra-visibility-change`
3269
+ - `interactive: boolean = true` (reflected) — renders each row as a toggle `<button>`; `false` renders
3270
+ plain, non-interactive rows
3271
+ - `label: string = ''` — accessible name for the `role="group"` wrapper
3272
+
3273
+ **Events:** `lyra-visibility-change` (`detail: { hiddenTypes }`, the complete updated array, fired
3274
+ after each toggle).
3275
+
3276
+ **Slots:** none.
3277
+
3278
+ **CSS parts:** `base`, `item` (a `<button>` when `interactive`, a plain `<div>` otherwise), `swatch`,
3279
+ `label`, `count`, `live-region` (the visually hidden filter-toggle announcement).
3280
+
3281
+ **Themeable custom properties:** no component-local tokens; reads `--lyra-graph-cat-1` through `-8`
3282
+ (the same computed-style fallback palette `lyra-graph`/`lyra-word-cloud` use) plus shared tokens.
3283
+
3284
+ **Optional peer deps:** none.
3285
+
3286
+ ```html
3287
+ <lyra-graph-legend id="legend"></lyra-graph-legend>
3288
+ <lyra-graph id="graph" style="height:480px"></lyra-graph>
3289
+ <script>
3290
+ const graph = document.getElementById('graph');
3291
+ const legend = document.getElementById('legend');
3292
+ legend.types = [{ id: 'person', label: 'Person', color: '#0969da' }, { id: 'org', label: 'Organization' }];
3293
+ legend.addEventListener('lyra-visibility-change', (e) => {
3294
+ legend.hiddenTypes = e.detail.hiddenTypes;
3295
+ graph.hiddenTypes = e.detail.hiddenTypes;
3296
+ });
3297
+ </script>
3298
+ ```
3299
+
3300
+ **Known gotchas:**
3301
+ - Ships no coupling to `lyra-graph`'s optional `d3-force`/`d3-drag`/`d3-zoom`/`d3-selection` peers —
3302
+ `types`/`counts`/`hiddenTypes` are plain data the host derives from a graph, never a live reference
3303
+ to one.
3304
+
3305
+ ---
3306
+
3307
+ ## `lyra-entity-card`
3308
+
3309
+ A dossier card for one knowledge-graph entity: type badge, description, key/value property rows,
3310
+ degree, community chip, plus a built-in "focus in graph" action. Never fetches or focuses a graph
3311
+ itself — `lyra-entity-activate` is a request a host routes into `lyra-graph`'s own
3312
+ `focusNode(id, options?)`.
3313
+
3314
+ **Properties:**
3315
+ - `entity: LyraEntity | null = null` (attribute: false) — `LyraEntity { id: string; label: string;
3316
+ type?: string; description?: string; properties?: Record<string, string | number>; degree?:
3317
+ number; communityId?: string }`; field names deliberately mirror `lyra-graph`'s `GraphNode`
3318
+ additions, so a graph node adapts into a `LyraEntity` with no mapping table; `null` renders the
3319
+ empty state
3320
+ - `types: NodeTypeStyle[] = []` (attribute: false) — the same `lyra-graph.nodeTypes`/
3321
+ `lyra-graph-legend.types` entry shape, resolving `entity.type` to a label/color/shape for the badge
3322
+ - `communityLabel: string = ''` (attribute `community-label`) — override text for the community chip
3323
+ - `showFocusButton: boolean = true` (attribute `show-focus-button`)
3324
+
3325
+ **Events:** `lyra-entity-activate` (`detail: { id }`, the built-in focus button was activated).
3326
+
3327
+ **Slots:** default (extra body content below the property rows, e.g. a `lyra-neighbor-list`),
3328
+ `actions` (extra header actions alongside the built-in focus button).
3329
+
3330
+ **CSS parts:** `base`, `header`, `type-badge`, `title` (`role="heading" aria-level="3"` by default),
3331
+ `description`, `properties`, `property` (one key/value row), `degree`, `community`, `actions`,
3332
+ `focus-button`, `empty` (shown when `entity` is `null`).
3333
+
3334
+ **Themeable custom properties:** shared tokens only; a data-driven `entity.type` color is applied as
3335
+ sanitized inline `--lyra-badge-*` overrides on the type badge only (the one "type color is
3336
+ data-driven by design" exception this library already grants graph nodes) — every other color comes
3337
+ from tokens.
3338
+
3339
+ **Optional peer deps:** none.
3340
+
3341
+ ```html
3342
+ <lyra-entity-card id="card"></lyra-entity-card>
3343
+ <script>
3344
+ document.getElementById('card').entity = {
3345
+ id: 'e1', label: 'Ada Lovelace', type: 'person',
3346
+ description: 'Mathematician', properties: { born: 1815 }, degree: 4,
3347
+ };
3348
+ document.getElementById('card').addEventListener('lyra-entity-activate', (e) => graph.focusNode(e.detail.id));
3349
+ </script>
3350
+ ```
3351
+
3352
+ **Known gotchas:**
3353
+ - The type badge's data-driven background uses a 10% (not this codebase's usual 16%) quiet-tint mix
3354
+ against `--lyra-color-surface` — the lower percentage is required to hold WCAG AA 4.5:1 text
3355
+ contrast for arbitrary, unvetted type colors.
3356
+
3357
+ ---
3358
+
3359
+ ## `lyra-entity-chip`
3360
+
3361
+ An inline `@entity` mention for agent prose: flow content, keyboard-focusable, with a hover/focus
3362
+ preview popover. The knowledge-graph sibling of `lyra-citation-badge`, reusing its interaction
3363
+ contract wholesale. Carries ids through events only — no entity data resolution, no navigation.
3364
+
3365
+ **Properties:**
3366
+ - `entityId: string = ''` (attribute `entity-id`)
3367
+ - `label: string = ''` — the chip's visible text
3368
+ - `type: string = ''` (reflected) — lets a host theme per type from CSS, e.g.
3369
+ `lyra-entity-chip[type='person'] { --lyra-entity-chip-color: ... }`
3370
+ - `typeLabel?: string` (attribute `type-label`) — optional spoken/visible type qualifier
3371
+
3372
+ **Events:** `lyra-entity-activate` (`detail: { id }`, click, or Enter while focused),
3373
+ `lyra-entity-open` (`detail: { id }`, dblclick, or Space while focused).
3374
+
3375
+ **Slots:** default — rich preview content (typically a compact `lyra-entity-card`), shown in a
3376
+ floating popover on hover/focus. No content means no popover and no hover affordance at all.
3377
+
3378
+ **CSS parts:** `base` (the clickable `<button>`), `label`, `popover`.
3379
+
3380
+ **Themeable custom properties:** `--lyra-entity-chip-color` (default `var(--lyra-color-brand)`,
3381
+ text/accent color), `--lyra-entity-chip-bg` (default `var(--lyra-color-brand-quiet)`).
3382
+
3383
+ **Optional peer deps:** none.
3384
+
3385
+ ```html
3386
+ <p>…first described by <lyra-entity-chip entity-id="e1" label="Ada Lovelace" type="person">
3387
+ <lyra-entity-card slot=""></lyra-entity-card>
3388
+ </lyra-entity-chip>.</p>
3389
+ ```
3390
+
3391
+ **Known gotchas:**
3392
+ - Reuses `lyra-citation-badge`'s exact "real preview content" detection (an assigned element with no
3393
+ other `slot`, or non-whitespace text) to decide whether a popover exists at all.
3394
+
3395
+ ---
3396
+
3397
+ ## `lyra-neighbor-list`
3398
+
3399
+ One entity's relationship rows: relation, direction, neighbor, with per-row navigate and
3400
+ expand-in-graph affordances. Never computes neighbors itself (the host derives rows from its own
3401
+ graph data) and never mutates a graph.
3402
+
3403
+ **Properties:**
3404
+ - `rows: LyraNeighborRow[] = []` (attribute: false) — `LyraNeighborRow { relation: string; direction:
3405
+ 'in' | 'out' | 'both'; node: LyraEntity }`
3406
+ - `groupByRelation: boolean = false` (attribute `group-by-relation`) — inserts a `group-header` row per
3407
+ distinct `relation`
3408
+ - `expandable: boolean = false` — renders a per-row expand-in-graph icon button
3409
+ - `virtualizeAt: number = 100` (attribute `virtualize-at`) — row count above which the list virtualizes
3410
+ - `label: string = ''`
3411
+
3412
+ **Events:** `lyra-entity-activate` (`detail: { id }`, a row's node button was activated),
3413
+ `lyra-node-expand` (`detail: { id }`, a row's expand button was activated — deliberately the same
3414
+ name and detail shape as `lyra-graph`'s own event, so one host handler serves both).
3415
+
3416
+ **Slots:** none.
3417
+
3418
+ **CSS parts:** `base` (`role="list"`), `group-header` (only when `groupByRelation`), `row`
3419
+ (`role="listitem"`), `direction` (`aria-hidden` glyph), `relation`, `node-label`, `node-meta`
3420
+ (secondary type/degree text, when present), `expand-button` (only when `expandable`), `empty`
3421
+ (shown when `rows` is empty).
3422
+
3423
+ **Themeable custom properties:** shared tokens only.
3424
+
3425
+ **Optional peer deps:** none.
3426
+
3427
+ ```html
3428
+ <lyra-neighbor-list expandable group-by-relation></lyra-neighbor-list>
3429
+ <script>
3430
+ document.querySelector('lyra-neighbor-list').rows = [
3431
+ { relation: 'works_for', direction: 'out', node: { id: 'e2', label: 'Analytical Engine Co.' } },
3432
+ ];
3433
+ </script>
3434
+ ```
3435
+
3436
+ **Known gotchas:**
3437
+ - `lyra-node-expand`'s detail shape is intentionally identical to `lyra-graph`'s own event of the
3438
+ same name, so a single listener wired to both handles "expand this node's neighborhood" uniformly.
3439
+
3440
+ ---
3441
+
3442
+ ## `lyra-path-strip`
3443
+
3444
+ A linear node → relation → node chain rendering "why A connects to B" (GraphRAG local-search
3445
+ reasoning paths) as a compact, horizontally scrollable strip. One-dimensional and presentational: no
3446
+ path finding, no branching, no per-element popovers.
3447
+
3448
+ **Properties:**
3449
+ - `path: LyraPathElement[] = []` (attribute: false) — a flat alternating sequence:
3450
+ `{ kind: 'node'; node: LyraEntity } | { kind: 'edge'; relation: string; directed?: boolean;
3451
+ reverse?: boolean }`
3452
+ - `label: string = ''`
3453
+
3454
+ **Events:** `lyra-entity-activate` (`detail: { id }`, a node element activated),
3455
+ `lyra-relation-activate` (`detail: { relation, sourceId?, targetId? }`, an edge element activated —
3456
+ source/target resolved from the adjacent node elements, `undefined` when the path is malformed at
3457
+ that position).
3458
+
3459
+ **Slots:** none.
3460
+
3461
+ **CSS parts:** `base` (hosts the delegated roving-tabindex keydown handler), `node` (a `<button>`),
3462
+ `relation` (a `<button>`), `arrow` (`aria-hidden`, logical — mirrors under RTL), `empty` (shown when
3463
+ `path` is empty).
3464
+
3465
+ **Themeable custom properties:** shared tokens only.
3466
+
3467
+ **Optional peer deps:** none.
3468
+
3469
+ ```html
3470
+ <lyra-path-strip></lyra-path-strip>
3471
+ <script>
3472
+ document.querySelector('lyra-path-strip').path = [
3473
+ { kind: 'node', node: { id: 'a', label: 'Ada Lovelace' } },
3474
+ { kind: 'edge', relation: 'wrote', directed: true },
3475
+ { kind: 'node', node: { id: 'b', label: 'Notes on the Analytical Engine' } },
3476
+ ];
3477
+ </script>
3478
+ ```
3479
+
3480
+ **Known gotchas:**
3481
+ - Purely presentational rendering of a caller-supplied path — it never computes shortest paths or
3482
+ fetches relationship data itself, and never branches (one linear chain per instance).
3483
+
3484
+ ---
3485
+
3486
+ ## `lyra-community-card`
3487
+
3488
+ A cluster/community summary card (GraphRAG community report): label, LLM summary excerpt, member
3489
+ count, member chips with overflow, and a drill-in action. Doesn't own community rendering on the
3490
+ graph or membership fetching — `lyra-drill` asks the host to load members/subgraph.
3491
+
3492
+ **Properties:**
3493
+ - `community: LyraCommunity | null = null` (attribute: false) — `LyraCommunity { id: string; label:
3494
+ string; summary?: string; memberCount?: number }`; `memberCount` is authoritative when it exceeds
3495
+ `members.length`; `null` renders the empty state
3496
+ - `members: LyraEntity[] = []` (attribute: false) — rendered as chips, up to `maxMembers`
3497
+ - `maxMembers: number = 8` (attribute `max-members`) — remaining members collapse into a "+N"
3498
+ overflow chip
3499
+ - `compact: boolean = false` (reflected) — omits the summary excerpt and member chips
3500
+
3501
+ **Events:** `lyra-drill` (`detail: { id }`, the drill button, header, or overflow chip — all three
3502
+ mean "show me this whole community"), `lyra-entity-activate` (`detail: { id }`, a member chip was
3503
+ activated).
3504
+
3505
+ **Slots:** `actions` — extra header actions alongside the built-in drill button.
3506
+
3507
+ **CSS parts:** `base`, `header`, `title` (`role="heading" aria-level="3"` wrapping a `<button>`),
3508
+ `member-count`, `summary` (omitted in `compact`), `members` (omitted in `compact`), `member`,
3509
+ `overflow` (the "+N" chip button), `drill-button`, `actions`, `empty` (shown when `community` is
3510
+ `null`).
3511
+
3512
+ **Themeable custom properties:** shared tokens only.
3513
+
3514
+ **Optional peer deps:** none.
3515
+
3516
+ ```html
3517
+ <lyra-community-card></lyra-community-card>
3518
+ <script>
3519
+ document.querySelector('lyra-community-card').community = { id: 'c1', label: 'Early computing pioneers', summary: 'A cluster of 19th-century mathematicians and engineers.', memberCount: 12 };
3520
+ </script>
3521
+ ```
3522
+
3523
+ **Known gotchas:**
3524
+ - `memberCount` (not `members.length`) is the authoritative displayed count whenever it's larger —
3525
+ useful when the host sends only a preview slice of members alongside the real total.
3526
+
3527
+ ---
3528
+
3529
+ ## `lyra-chunk-inspector`
3530
+
3531
+ A ranked retrieved-chunks list: relevance score bars with tier tones, expandable chunk text, and the
3532
+ deep-link event that lands a chunk in `lyra-document-viewer`. Never fetches, ranks, or dedupes; never
3533
+ opens documents itself.
3534
+
3535
+ **Properties:**
3536
+ - `chunks: LyraChunk[] = []` (attribute: false) — `LyraChunk { id: string; text: string; score:
3537
+ number; sourceId: string; title?: string; page?: string | number; anchor?: LyraChunkAnchor }`;
3538
+ `score` is 0–1, `title` falls back to a localized "untitled source", `anchor` (the same
3539
+ discriminated union `lyra-document-viewer.anchor` accepts — page/text-quote/fragment/line-range/
3540
+ cell-range/cfi/time-range/region/node-path) is carried through `lyra-chunk-open` verbatim
3541
+ - `thresholds: { high: number; medium: number } = { high: 0.75, medium: 0.5 }` (attribute: false) —
3542
+ score-bar tier cutoffs
3543
+ - `sort: 'score' | 'none' = 'score'`
3544
+ - `activeId: string = ''` (attribute `active-id`)
3545
+ - `virtualizeAt: number = 50` (attribute `virtualize-at`)
3546
+ - `compact: boolean = false` (reflected) — hides the text preview/toggle, title/score row only
3547
+ - `label: string = ''`
3548
+
3549
+ **Events:** `lyra-chunk-open` (`detail: { id, sourceId, anchor? }`, a chunk's title/open button was
3550
+ activated — the event a host routes into `lyra-document-viewer`, setting `src` from `sourceId` and
3551
+ `anchor` from the chunk's own), `lyra-expand` (`detail: { id, expanded }`, a chunk's text toggle was
3552
+ activated).
3553
+
3554
+ **Slots:** none.
3555
+
3556
+ **CSS parts:** `base` (`role="group"`), `chunk` (`role="listitem"`), `score` (visible percent text),
3557
+ `score-bar` (`aria-hidden` track), `score-fill` (tone-mapped fill), `open-button`, `title` (the
3558
+ `<span>` inside `open-button` carrying the visible title text), `text` (line-clamped unless
3559
+ expanded, omitted when `compact`), `toggle` ("Show more"/"Show less", omitted when `compact`),
3560
+ `empty` (shown when `chunks` is empty).
3561
+
3562
+ **Themeable custom properties:** shared tokens only.
3563
+
3564
+ **Optional peer deps:** none.
3565
+
3566
+ ```html
3567
+ <lyra-chunk-inspector></lyra-chunk-inspector>
3568
+ <script>
3569
+ const inspector = document.querySelector('lyra-chunk-inspector');
3570
+ inspector.chunks = [
3571
+ { id: 'c1', text: 'Revenue grew 12% year over year…', score: 0.91, sourceId: 'doc-1', title: 'Q3 report', page: 4 },
3572
+ ];
3573
+ inspector.addEventListener('lyra-chunk-open', (e) => documentViewer.openAt(e.detail.sourceId, e.detail.anchor));
3574
+ </script>
3575
+ ```
3576
+
3577
+ **Known gotchas:**
3578
+ - `title` and `open-button` are split into two separate parts (rather than one dual-part-name
3579
+ element) because an exact-match `[part="..."]` CSS attribute selector — as this component's own
3580
+ tests use — cannot match a multi-token `part` attribute value.
3581
+
3582
+ ---
3583
+
3584
+ ## `lyra-source-picker`
3585
+
3586
+ A checkbox tree/list scoping which sources ground the next answer: tri-state folders, select-all,
3587
+ type icons, search. **Not `FormAssociated`, deliberately**: this is a scoping panel, not a form
3588
+ control — the selection is immediate app state consumed by the next retrieval call, exactly the
3589
+ stance `lyra-tool-select-dialog` already takes.
3590
+
3591
+ **Properties:**
3592
+ - `sources: LyraSourceEntry[] = []` (attribute: false) — `LyraSourceEntry { id: string; label:
3593
+ string; mimeType?: string; name?: string; children?: LyraSourceEntry[] }`; flat (no `children`) or
3594
+ a tree — presence of `children` makes a row a group/folder with tri-state select
3595
+ - `selectedIds: string[] = []` (attribute: false) — controlled; the host assigns this back from
3596
+ `lyra-sources-change`
3597
+ - `showSelectAll: boolean = true` (attribute `show-select-all`)
3598
+ - `searchable: boolean = true`
3599
+ - `label: string = ''`
3600
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — overrides the tree's computed
3601
+ accessible name; wins over `label` and the localized default, and attribute-reflects from a
3602
+ host-level `aria-label` so plain markup gets ARIA-name forwarding
3603
+
3604
+ **Events:** `lyra-sources-change` (`detail: { selectedIds }`, the complete updated leaf-id array,
3605
+ fired after every toggle including select-all).
3606
+
3607
+ **Slots:** none.
3608
+
3609
+ **CSS parts:** `base`, `search` (the built-in filter `lyra-input`, only when `searchable`),
3610
+ `select-all` (only when `showSelectAll`), `summary` ("{selected} of {total} selected"), `tree`
3611
+ (`role="tree"`), `item` (`role="treeitem"`), `checkbox` (tri-state glyph), `icon` (the
3612
+ `lyra-file-icon` type badge), `label`, `empty` (`noData` when `sources` is empty, `noMatches` when a
3613
+ filter empties the tree).
3614
+
3615
+ **Themeable custom properties:** shared tokens only.
3616
+
3617
+ **Optional peer deps:** none.
3618
+
3619
+ ```html
3620
+ <lyra-source-picker></lyra-source-picker>
3621
+ <script>
3622
+ const picker = document.querySelector('lyra-source-picker');
3623
+ picker.sources = [
3624
+ { id: 'folder-1', label: 'Reports', children: [{ id: 'doc-1', label: 'Q3.pdf', mimeType: 'application/pdf' }] },
3625
+ ];
3626
+ picker.addEventListener('lyra-sources-change', (e) => (retrievalScope = e.detail.selectedIds));
3627
+ </script>
3628
+ ```
3629
+
3630
+ **Known gotchas:**
3631
+ - Deliberately not form-associated — `lyra-sources-change` is the only wiring; there's no
3632
+ `name`/`value`/`FormData` participation the way a genuine form control would have.
3633
+
3634
+ ---
3635
+
3636
+ ## `lyra-provenance-panel`
3637
+
3638
+ The grounding breakdown for one answer: a sectioned disclosure panel (Entities / Relationships /
3639
+ Communities / Text chunks) composing this family's own pieces. The chat ↔ graph ↔ document glue
3640
+ component. Pure projection + event conduit: no fetching, no graph/viewer imports, no persistence.
3641
+
3642
+ **Properties:**
3643
+ - `provenance: LyraProvenance | null = null` (attribute: false) — `LyraProvenance { entities?:
3644
+ LyraEntity[]; relationships?: { path: LyraPathElement[] }[]; communities?: LyraCommunity[]; chunks?:
3645
+ LyraChunk[] }`; each present array renders through the matching sibling component (`lyra-entity-
3646
+ chip` row, one `lyra-path-strip` per relationship, `lyra-community-card`, `lyra-chunk-inspector`);
3647
+ `null` or every section empty renders the overall empty state
3648
+ - `types: NodeTypeStyle[] = []` (attribute: false) — forwarded to the Entities section's chips
3649
+ - `thresholds: { high: number; medium: number } = { high: 0.75, medium: 0.5 }` (attribute: false) —
3650
+ forwarded to the Text chunks section's `lyra-chunk-inspector`
3651
+ - `label: string = ''`
3652
+
3653
+ **Events:** `lyra-toggle` (`detail: { section, expanded }`, a section header was toggled —
3654
+ `section` is `'entities' | 'relationships' | 'communities' | 'chunks'`).
3655
+
3656
+ **Slots:** none.
3657
+
3658
+ **CSS parts:** `base`, `section`, `header` (a section's disclosure `<button>`), `count` (a section's
3659
+ item-count badge), `body` (`hidden` while collapsed), `empty` (shown when every section is empty).
3660
+
3661
+ **Themeable custom properties:** shared tokens only.
3662
+
3663
+ **Optional peer deps:** none.
3664
+
3665
+ ```html
3666
+ <lyra-provenance-panel></lyra-provenance-panel>
3667
+ <script>
3668
+ document.querySelector('lyra-provenance-panel').provenance = {
3669
+ entities: [{ id: 'e1', label: 'Ada Lovelace', type: 'person' }],
3670
+ chunks: [{ id: 'c1', text: 'Revenue grew 12%…', score: 0.91, sourceId: 'doc-1' }],
3671
+ };
3672
+ </script>
3673
+ ```
3674
+
3675
+ **Known gotchas:**
3676
+ - Composes `lyra-entity-chip`, `lyra-path-strip`, `lyra-community-card`, and `lyra-chunk-inspector`
3677
+ directly rather than reimplementing their rendering — events from those inner components (e.g.
3678
+ `lyra-entity-activate`, `lyra-chunk-open`) still bubble/compose up through this panel's light DOM
3679
+ for the host to handle in one place.
3680
+
3681
+ ---
3682
+
3683
+ ## `lyra-mind-map`
3684
+
3685
+ A radial expandable topic tree (NotebookLM Mind Maps): a spatial overview of a topic hierarchy where
3686
+ activating a topic drills in or hands the topic to the chat. Hierarchy, not network — no cross-links,
3687
+ no force simulation, no communities, no edge labels (that's `lyra-graph`). Zero-dependency SVG; the
3688
+ radial layout is closed-form arithmetic, in its own `mind-map-layout.ts` module, mirroring
3689
+ `lyra-word-cloud`'s dependency-free precedent.
3690
+
3691
+ **Properties:**
3692
+ - `topics: LyraTopic[] = []` (attribute: false) — `LyraTopic { id: string; label: string; children?:
3693
+ LyraTopic[] }`; a single root sits at the center, multiple roots hang off an implicit center hub
3694
+ - `label: string = ''` — accessible name for the SVG group and the implicit hub's text
3695
+ - `expandDepth: number = 1` (attribute `expand-depth`) — initial expansion depth (root + first
3696
+ ring); expansion state afterward is component-managed per topic id and survives `topics`
3697
+ reassignment
3698
+
3699
+ **Events:** `lyra-topic-select` (`detail: { id }`, a *leaf* topic was activated),
3700
+ `lyra-topic-toggle` (`detail: { id, expanded }`, a parent topic was activated, or auto-expanded by
3701
+ keyboard descent).
3702
+
3703
+ **Slots:** none.
3704
+
3705
+ **CSS parts:** `base`, `svg` (the single-tab-stop focus target), `node`, `node-label`, `link`
3706
+ (parent-child connector), `focus-ring` (keyboard focus ring), `live-region` (visually hidden
3707
+ announcement region), `empty` (shown when `topics` is empty).
3708
+
3709
+ **Themeable custom properties:** `--lyra-mind-map-ring-gap` (default `6rem`, radius step per depth
3710
+ ring).
2706
3711
 
2707
3712
  **Optional peer deps:** none.
2708
3713
 
2709
3714
  ```html
2710
- <lyra-tree></lyra-tree>
3715
+ <lyra-mind-map style="height:480px" expand-depth="2"></lyra-mind-map>
2711
3716
  <script>
2712
- document.querySelector('lyra-tree').data = [
2713
- {
2714
- id: '1',
2715
- label: 'Root',
2716
- description: 'Two child documents',
2717
- accessibleLabel: 'Root, two child documents',
2718
- icon: document.createTextNode('◇'),
2719
- children: [{ id: '1a', label: 'Child A' }, { id: '1b', label: 'Child B', badge: 3 }],
2720
- },
3717
+ document.querySelector('lyra-mind-map').topics = [
3718
+ { id: 'root', label: 'Computing history', children: [
3719
+ { id: 'people', label: 'People', children: [{ id: 'ada', label: 'Ada Lovelace' }] },
3720
+ { id: 'machines', label: 'Machines' },
3721
+ ] },
2721
3722
  ];
2722
3723
  </script>
2723
3724
  ```
2724
3725
 
2725
3726
  **Known gotchas:**
2726
- - all four previously-known ARIA gaps in this pair are fixed: the treeitem row is now genuinely
2727
- keyboard-operable with a roving tabindex and full arrow-key navigation (not just the expand/collapse
2728
- button); the expanded-children `role="group"` is now a real DOM descendant of its `role="treeitem"`
2729
- host rather than a shadow-DOM sibling; by-id reconciliation (preserving `expanded` state across
2730
- data reassignment) now applies at every depth via a keyed `repeat()`, not just depth 0; and
2731
- `role="tree"` now has an accessible name via the new `label` property.
2732
- - `lyra-tree`'s `getUpdateComplete()` cascades into every currently-known descendant
2733
- `<lyra-tree-node>`'s own `updateComplete` (see `update-cascade.ts`) so that code awaiting the
2734
- tree's `updateComplete` (e.g. after `focusNode()`) doesn't run before an arbitrarily-nested node has
2735
- actually finished rendering its pushed-down `activeId`/`tabIndex` — one more pending update per
2736
- depth level, otherwise.
2737
- - row enrichment is intentionally structured rather than an unrestricted renderer: use `icon`,
2738
- `label`, `description`, `badge`, and `accessibleLabel`. This keeps the host as the single
2739
- `role="treeitem"` interaction target and preserves the APG keyboard model.
3727
+ - A user's explicit expand/collapse only ever overrides the `depth < expandDepth` default in the
3728
+ direction chosen reassigning `topics` (even with the same ids) never silently discards that
3729
+ override.
3730
+ - Node-position transitions use `--lyra-transition-base`, which already collapses to near-zero under
3731
+ `prefers-reduced-motion: reduce` globally, so expansion snaps rather than tweening for a
3732
+ reduced-motion user with no extra branching in this component.
2740
3733
 
2741
3734
  ---
2742
3735
 
@@ -2759,6 +3752,12 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2759
3752
  noTooltip?: boolean; axis?: 'y'|'y2'; pointColors?: string[]; pointRadius?: number; type?:
2760
3753
  'line'|'bar' }`
2761
3754
  - `legend: boolean = false`
3755
+ - `legendPosition: LyraChartLegendPosition = 'top'` (attribute `legend-position`) — places the
3756
+ legend at `top`, `right`, `bottom`, or `left`; `auto` chooses right above 480px and bottom below
3757
+ that allocation width
3758
+ - `valueFormatter?: LyraChartValueFormatter` (attribute: false) — formats numeric tick, tooltip,
3759
+ and legend values; the callback receives the value and `'tick'`, `'tooltip'`, or `'legend'`
3760
+ context
2762
3761
  - `area: boolean = false`
2763
3762
  - `zoom: boolean = false`
2764
3763
  - `height: string = '280px'`
@@ -2780,6 +3779,9 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2780
3779
  localized data/trend summary
2781
3780
  - `showDataTable: boolean = false` (attribute `show-data-table`) — makes the always-available
2782
3781
  accessible data table visible rather than screen-reader-only
3782
+ - `chartArea: LyraChartArea | undefined` (readonly) — current Chart.js chart-area geometry in
3783
+ canvas-local coordinates (`top`, `left`, `right`, `bottom`, `width`, `height`), when a chart is
3784
+ drawn
2783
3785
 
2784
3786
  **Methods:** `resetZoom()` (reset any active zoom/pan to the original view), `refreshTheme()`
2785
3787
  (forces a redraw so the `--lyra-chart-*` tokens below are re-read from the current computed style —
@@ -2791,9 +3793,11 @@ the escape hatch for a consumer's own theme-toggle handler to call when it flips
2791
3793
  a data point/segment, for any chart type, not just bar; `detail: { datasetIndex: number, index:
2792
3794
  number, label: string | undefined, value: unknown }`)
2793
3795
 
2794
- **Slots:** `data-table` — an optional consumer-provided accessible table alternative.
3796
+ **Slots:** `data-table` — an optional consumer-provided accessible table alternative; `center` —
3797
+ optional overlay content positioned at the chart area's center, useful for doughnut and pie totals.
2795
3798
 
2796
- **CSS parts:** `base`, `canvas`, `reset-zoom-button`, `description`, `data-table`
3799
+ **CSS parts:** `base`, `canvas`, `reset-zoom-button`, `description`, `data-table`, `center` (the
3800
+ chart-area-centered wrapper for the `center` slot)
2797
3801
 
2798
3802
  **Themeable custom properties:** `--lyra-chart-height` (set programmatically on the host from the
2799
3803
  `height` property — must be read from the host, not a shadow-tree descendant, since custom
@@ -2908,6 +3912,10 @@ passthrough). Not a subclass of `LyraChart`.
2908
3912
  - `pointText?: (label: string, value: number, datasetIndex: number) => string` (attribute: false) —
2909
3913
  overrides the per-bar/per-point `<title>`/`aria-label` tooltip text (mirrors `lyra-heatmap`'s
2910
3914
  `cellText`). Falls back to the built-in raw-value template when unset.
3915
+ - `legendText?: (label: string, datasetIndex: number) => string` (attribute: false) — appends
3916
+ formatter-supplied text (e.g. a value or percentage share) after each series' label in the
3917
+ built-in legend row, mirroring `pointText`/`tickFormat`'s opt-in-hook convention. Falls back to
3918
+ the label alone when unset; no-op while `legend` is `false`.
2911
3919
  - `roundedBars: boolean = false` (attribute `rounded-bars`, bar type only) — draws each bar as a
2912
3920
  rounded-top-corner shape instead of a square-cornered `<rect>`.
2913
3921
  - `skipZero: boolean = false` (attribute `skip-zero`, bar type only) — omits a bar entirely (no
@@ -2950,8 +3958,9 @@ fresh, small SVG render is cheaper and more correct than a lossy cache.
2950
3958
 
2951
3959
  **CSS parts:** `base`, `grid-line`, `axis-label`, `axis-title`, `bar` (each bar rect; carries
2952
3960
  `data-selected` when its category index is in `selectedIndex`), `line`, `point`, `legend`,
2953
- `legend-item`, `legend-swatch`, `live-region` (the current mark announcement for keyboard users),
2954
- `data-list` (a visually hidden list of all plotted data points).
3961
+ `legend-item`, `legend-swatch`, `legend-text` (extra per-item text after the series label,
3962
+ rendered only when `legendText` is set), `live-region` (the current mark announcement for keyboard
3963
+ users), `data-list` (a visually hidden list of all plotted data points).
2955
3964
 
2956
3965
  **Themeable custom properties:** `--lyra-chart-height` (same host-level property as `lyra-chart`);
2957
3966
  `--lyra-chart-grid-color`, `--lyra-chart-tick-color`, `--lyra-chart-legend-color` — same token
@@ -3111,8 +4120,8 @@ independently of the base `chart-loader.ts`).
3111
4120
 
3112
4121
  ## `lyra-map`
3113
4122
 
3114
- A `maplibre-gl` wrapper with a declarative legend and a single choropleth GeoJSON fill layer, plus a
3115
- raw `map` escape hatch for anything unexposed.
4123
+ A `maplibre-gl` wrapper with a declarative legend, a single choropleth GeoJSON fill layer, markers,
4124
+ and additive plain-GeoJSON `dataLayers`, plus a raw `map` escape hatch for anything unexposed.
3116
4125
 
3117
4126
  **Properties:**
3118
4127
  - `center: [number, number] = [0, 0]`
@@ -3137,6 +4146,17 @@ raw `map` escape hatch for anything unexposed.
3137
4146
  escaped) when the content is plain text. A marker whose `color` changes for a persisting `id`
3138
4147
  can't be recolored in place (no `Marker.setColor()`) and is torn down/reconstructed instead — see
3139
4148
  gotchas.
4149
+ - `dataLayers: GeoJsonDataLayer[] = []` (attribute: false) — `GeoJsonDataLayer { sourceId: string;
4150
+ geojson: GeoJSON.Feature | GeoJSON.FeatureCollection; tone?: 'accent' | 'success' | 'warning' |
4151
+ 'danger' | 'neutral' }`. Each entry adds one GeoJSON source plus three layers
4152
+ (`${sourceId}-fill`/`${sourceId}-line`/`${sourceId}-circle`, filtered by geometry type so a mixed
4153
+ `FeatureCollection` renders correctly across all three), colored from the matching `--lyra-color-*`
4154
+ token (`tone` defaults to `'accent'` → `--lyra-color-brand`). Independent of `choropleth` — no
4155
+ `field`/`stops` color-interpolation, just the geometry rendered in a flat tone; use `choropleth`
4156
+ instead when you need a data-driven color ramp. Reconciled by `sourceId` the same way `choropleth`
4157
+ is: an entry whose `sourceId` persists across a `dataLayers` reassignment gets its GeoJSON updated
4158
+ in place (`setData()`), one that's dropped has its source/layers removed, and a genuinely new
4159
+ `sourceId` gets a new source/layers — nothing leaks on removal, style change, or disconnect.
3140
4160
  - `label: string = ''` — accessible name for the map region, applied as `[part="base"]`'s
3141
4161
  `aria-label`. A plain `aria-label` attribute on the host itself is honored as a fallback when
3142
4162
  `label` is left unset, matching `lyra-slider`/`lyra-checkbox`/`lyra-switch`; with neither set, it
@@ -3181,9 +4201,9 @@ exists and was hit)
3181
4201
  `removeSource` on whatever was previously applied before adding the new one (or nothing, if
3182
4202
  cleared).
3183
4203
  - `mapStyle` changes after construction now call `setStyle()` (in addition to `center`/`zoom`
3184
- already calling `setCenter`/`setZoom`) — the choropleth is automatically re-applied once the new
3185
- style's own `'style.load'` fires, since a style change wipes every layer/source maplibre-gl knows
3186
- about.
4204
+ already calling `setCenter`/`setZoom`) — the choropleth and `dataLayers` are both automatically
4205
+ re-applied once the new style's own `'style.load'` fires, since a style change wipes every
4206
+ layer/source maplibre-gl knows about.
3187
4207
  - Point markers now have a declarative API (`markers`, above) with popup support — the `.map` escape
3188
4208
  hatch and manual `new maplibregl.Marker()` are no longer the only way to place pins.
3189
4209
  - a marker whose `color` changes for a persisting `id` is torn down and reconstructed (maplibre-gl's
@@ -3704,6 +4724,9 @@ wrapper at all, so existing text-only tabs are unaffected.
3704
4724
  - `active: string = ''` (reflected) — the active tab's `slot`/id; falls back to the first enabled
3705
4725
  tab whenever the current value doesn't resolve to one (including on every children/attribute
3706
4726
  change, tracked via a `MutationObserver`)
4727
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — accessible name applied to the
4728
+ `role="tablist"` strip; attribute-reflects from a host-level `aria-label`. Unset, the tablist
4729
+ renders without an `aria-label` (there is no localized default name).
3707
4730
 
3708
4731
  **Events:** `lyra-tabs-change` (`detail: { tabId: string }`) — fired when the active tab changes via
3709
4732
  click or keyboard. Not fired when `active` self-corrects to a valid tab (initial default, or a tab
@@ -3766,6 +4789,9 @@ convention).
3766
4789
  - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — `'horizontal'` (the default)
3767
4790
  lays steps out in a row (Left/Right, RTL-aware, navigate); `'vertical'` stacks them (Up/Down
3768
4791
  navigate instead, no RTL swap needed).
4792
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — accessible name applied to the
4793
+ `role="tablist"` step strip; attribute-reflects from a host-level `aria-label`. Unset, the
4794
+ tablist renders without an `aria-label` (there is no localized default name).
3769
4795
 
3770
4796
  **Events:** `lyra-step-select` (`detail: { index, id }`) — fired on click, or Enter/Space while
3771
4797
  focused, on a non-`disabled` step. Cancelable, though this component takes no default action of its
@@ -4086,22 +5112,32 @@ stack overflow on cyclic `data`.
4086
5112
  - `search: string = ''` — case-insensitive substring match against keys/values; matches are
4087
5113
  highlighted and their ancestors auto-expanded
4088
5114
 
5115
+ **Methods:** `runSearch(query)` sets the declarative `search` property and awaits the recompute,
5116
+ resolving the match count — named distinctly from `search` because a class member can't share a name
5117
+ with a reactive property. `searchNext()`/`searchPrevious()` advance/step back a match cursor
5118
+ (wrapping) and scroll the active match into view, resolving `false` when there are no matches.
5119
+ `clearSearch()` resets `search` to `''`, clearing all matches and the cursor.
5120
+
4089
5121
  **Events:** `lyra-copy` (`detail: { text: string }`) — fired by the top-level copy button or a
4090
5122
  per-node one. Fires even when `navigator.clipboard` is unavailable or the write silently failed
4091
5123
  (a rejected `writeText()` is swallowed), so a consumer can still observe copy *intent* — the event
4092
5124
  is not a confirmation that the OS clipboard was actually reached. Copying a circular `data` value
4093
5125
  serializes safely, substituting the same `Circular reference` marker the tree view renders, instead
4094
- of throwing.
5126
+ of throwing. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — fired whenever the
5127
+ search query, match count, or active-match cursor changes, from `runSearch()`/`searchNext()`/
5128
+ `searchPrevious()`/`clearSearch()`, or a direct `search`/`data` property write.
4095
5129
 
4096
5130
  **Slots:** none — the tree is rendered entirely from `data`.
4097
5131
 
4098
5132
  **CSS parts:** `base` (root scroll container, respects `max-height`), `toolbar` (wrapper around the
4099
5133
  top-level copy button, only rendered when `copyable`), `tree` (wrapper around the rendered node
4100
- tree), `key` (an object property key or array index label, `data-match` while it matches `search`),
5134
+ tree), `key` (an object property key or array index label, `data-match` while it matches `search`,
5135
+ `data-active` while it is the current `searchNext()`/`searchPrevious()` cursor position),
4101
5136
  `value` (a primitive value's text — carries `data-type` of
4102
- `string`/`number`/`boolean`/`null`/`undefined`/`circular` for per-type coloring, and `data-match`
4103
- while it matches `search`), `bracket` (a `{`, `}`, `[`, or `]` delimiter), `toggle` (a container
4104
- node's expand/collapse button; hidden but present for row alignment on leaf/empty nodes),
5137
+ `string`/`number`/`boolean`/`null`/`undefined`/`circular` for per-type coloring, `data-match`
5138
+ while it matches `search`, and `data-active` while it is the current cursor position), `bracket` (a
5139
+ `{`, `}`, `[`, or `]` delimiter), `toggle` (a container node's expand/collapse button; hidden but
5140
+ present for row alignment on leaf/empty nodes),
4105
5141
  `copy-button` (a copy-to-clipboard button — the top-level one in `toolbar` (aria-label "Copy JSON to
4106
5142
  clipboard") or a per-node one (aria-label `Copy ${key/type}`, e.g. "Copy age"); only rendered when
4107
5143
  `copyable`)
@@ -4246,6 +5282,15 @@ instance on a page shares one load. `heading`/`code`/`blockquote`/`table`/`link`
4246
5282
  rendered through a `marked` renderer override that injects `part="..."` attributes directly into the
4247
5283
  produced HTML in a single pass (no second DOM walk after insertion).
4248
5284
 
5285
+ Fenced code blocks are also syntax-highlighted via the same optional `shiki` peer `<lyra-code-block>`
5286
+ uses, gated by `highlightCode` (default `true`). This is a pure upgrade, not a separate opt-in: it's
5287
+ already transparently gated by whether `shiki` is installed at all, so an app that never installs the
5288
+ peer sees byte-identical output to before this property existed. The very first render of any content
5289
+ is always plain text/code (identical to today's output); highlighting arrives as an asynchronous
5290
+ upgrade one render later once shiki resolves and the block's language is tokenized. No highlighting
5291
+ is attempted while `streaming` is `true` — it applies once a stream settles, adding no per-chunk cost
5292
+ while content is still arriving.
5293
+
4249
5294
  **Properties:**
4250
5295
  - `content: string = ''` — the Markdown source to render
4251
5296
  - `sanitize: boolean = true` — sanitize `marked`'s HTML output with DOMPurify before rendering
@@ -4280,6 +5325,27 @@ produced HTML in a single pass (no second DOM walk after insertion).
4280
5325
  - `streaming: boolean = false` (reflected) — marks the host `aria-busy="true"` while partial Markdown
4281
5326
  is still arriving and lets consumers target `lyra-markdown[streaming]`; busy state also remains
4282
5327
  true while parser dependencies are loading
5328
+ - `highlightCode: boolean = true` (attribute `highlight-code`) — syntax-highlights fenced code
5329
+ blocks via the optional `shiki` peer. `true` (the default) upgrades every fenced block once the
5330
+ peer is available; set `false` to keep plain output even when `shiki` is installed. No effect
5331
+ while `streaming` is `true`
5332
+ - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — same shape and purpose as
5333
+ `<lyra-code-block>`'s own `languages`: a fine-grained, explicit language-grammar bundle scoping
5334
+ shiki's build output to just those grammars instead of its full ~200-language bundle. Forwarded
5335
+ verbatim to `loadShikiHighlighterCore()`. Unset (the default) uses the default full-bundle loader
5336
+ - `languagesOnly: boolean = false` (attribute `languages-only`) — same purpose as
5337
+ `<lyra-code-block>`'s own `languagesOnly`: skips the default full-bundle loader entirely, so a
5338
+ fenced block whose language isn't in `languages` falls back to plain unhighlighted text rather
5339
+ than reaching for the full bundle. No effect unless `languages` is also set
5340
+ - `headingAnchors: boolean = false` (attribute `heading-anchors`) — stamps a computed
5341
+ GitHub-slugger-style slug as `id` on every rendered heading.
5342
+ - `math: boolean = false` — renders `$inline$` and `$$block$$` TeX via the optional `katex` peer,
5343
+ lazy-loaded the same way as `marked`/`dompurify`/`shiki`.
5344
+ - `anchorKinds: readonly ('fragment' | 'text-quote')[]` (readonly) — the anchor kinds this
5345
+ component resolves for the shared anchor-target contract.
5346
+
5347
+ **Methods:** `getHeadingTree()` returns the document-ordered heading outline (`{ level, text, slug
5348
+ }[]`) computed on every parse, regardless of `headingAnchors`.
4283
5349
 
4284
5350
  **Events:** `lyra-link-click` (`detail: { href: string, internal: true }`, fired — with the click
4285
5351
  prevented — when a rendered link's `href` starts with `internal-link-prefix`; ordinary external
@@ -4304,7 +5370,10 @@ Menlo, Consolas, monospace` — the code/code-block font; component-specific sin
4304
5370
  **Optional peer deps:** `marked`, `dompurify` (both lazy-loaded via `markdown-loader.ts`'s
4305
5371
  `loadMarkdownDeps()`, mirroring `chart-loader.ts`'s two-independent-optional-peers shape). Each half
4306
5372
  is loaded and caught independently — a consumer who installs only `marked` and explicitly sets
4307
- `sanitize="false"` (so `dompurify` is never needed) is a valid, supported combination.
5373
+ `sanitize="false"` (so `dompurify` is never needed) is a valid, supported combination. Also `shiki`,
5374
+ the same optional peer `<lyra-code-block>` uses, for `highlightCode`'s fenced-block syntax
5375
+ highlighting — independent of the `marked`/`dompurify` pair, and its absence never blocks rendering
5376
+ (fenced blocks simply stay unhighlighted).
4308
5377
 
4309
5378
  ```html
4310
5379
  <lyra-markdown
@@ -4350,6 +5419,65 @@ legible text in the meantime.
4350
5419
 
4351
5420
  ---
4352
5421
 
5422
+ ## `lyra-markdown-core`
5423
+
5424
+ A build-lean sibling of `<lyra-markdown>` above, for a consumer whose `languages` map already covers
5425
+ every language it will ever render — mirrors `<lyra-code-block-core>`'s relationship to
5426
+ `<lyra-code-block>`. Where `<lyra-markdown>` unconditionally calls `loadShikiHighlighter()` — the
5427
+ default ~200-language dynamic-import table loader, whose bundled lookup table a bundler can't
5428
+ statically narrow away even when a consumer's `languagesOnly` flag makes it unreachable at runtime —
5429
+ this component's own module never imports or calls that function at all; it only ever calls
5430
+ `loadShikiHighlighterCore(languages)`, so a consumer importing this entry point instead of
5431
+ `markdown.js` gets a build genuinely free of shiki's full language table.
5432
+
5433
+ A fenced code block whose language isn't a key in `languages` always renders the plain-text fallback
5434
+ — there is no default/full-table highlighter here to fall back to, the same default (not degraded)
5435
+ rendering path as `<lyra-code-block-core>`'s identical contract. Every other capability — GFM tables,
5436
+ links, blockquotes, images, heading anchors, `getHeadingTree()`, `fragment`/`text-quote` anchor-target
5437
+ support (`highlights`, `activeHighlightId`, `scrollToAnchor()`, the `lyra-highlight-activate`/
5438
+ `lyra-text-select`/`lyra-anchor-result` events), math via the optional `katex` peer, the sanitize/
5439
+ `escapeHtml`/streaming fallback matrix and known gotchas — is identical to `<lyra-markdown>`; see that
5440
+ section above for the full write-up of shared behavior. There is no `languagesOnly` property here —
5441
+ meaningless without a full-table fallback to gate, matching `<lyra-code-block-core>` having none
5442
+ either.
5443
+
5444
+ **Properties:** `content: string = ''`, `sanitize: boolean = true`, `escapeHtml: boolean = false`
5445
+ (attribute `escape-html`), `gfm: boolean = true`, `linkTarget: string | null = '_blank'` (attribute
5446
+ `link-target`), `internalLinkPrefix: string = ''` (attribute `internal-link-prefix`),
5447
+ `headingOffset: number = 0` (attribute `heading-offset`), `eagerLoad: boolean = false` (attribute
5448
+ `eager-load`), `streaming: boolean = false` (reflected), `highlightCode: boolean = true` (attribute
5449
+ `highlight-code`), `languages: Record<string, ShikiLanguageInput> = {}` (attribute: false) — required,
5450
+ unlike `<lyra-markdown>`'s optional `languages?:`; empty (the default) means every fenced block stays
5451
+ unhighlighted permanently, `headingAnchors: boolean = false` (attribute `heading-anchors`),
5452
+ `math: boolean = false`, `anchorKinds: readonly ('fragment' | 'text-quote')[]` (readonly).
5453
+
5454
+ **Methods:** `getHeadingTree()` — same contract as `<lyra-markdown>`'s own.
5455
+
5456
+ **Events:** `lyra-link-click`, `lyra-render-error`, `lyra-highlight-activate`, `lyra-text-select`,
5457
+ `lyra-anchor-result` — identical detail shapes to `<lyra-markdown>`'s own.
5458
+
5459
+ **Slots:** none — content comes from the `content` property, not light-DOM children.
5460
+
5461
+ **CSS parts:** `content`, `heading`, `paragraph`, `list`, `code-block`, `inline-code`, `link`,
5462
+ `table`, `blockquote`, `img`, `math` — identical to `<lyra-markdown>`'s own parts.
5463
+
5464
+ **Optional peer deps:** `marked`, `dompurify` (both lazy-loaded, same as `<lyra-markdown>`), `katex`
5465
+ (for `math`). Does *not* depend on the full `shiki` package's default entry point — only
5466
+ `shiki/core`/`shiki/engine/oniguruma`/`shiki/langs/*`, the same fine-grained subset
5467
+ `<lyra-code-block-core>` depends on.
5468
+
5469
+ ```html
5470
+ <lyra-markdown-core
5471
+ content="# Report&#10;&#10;\`\`\`python&#10;print('hi')&#10;\`\`\`"
5472
+ .languages=${{ python }}
5473
+ ></lyra-markdown-core>
5474
+ <script type="module">
5475
+ import python from 'shiki/langs/python.mjs';
5476
+ </script>
5477
+ ```
5478
+
5479
+ ---
5480
+
4353
5481
  ## `lyra-chat-message`
4354
5482
 
4355
5483
  A role-based message bubble *shell* for a chat/agent conversation surface. It renders none of the
@@ -4381,6 +5509,10 @@ conversation-surface level).
4381
5509
  rendered) — mirrors `lyra-widget`'s identical `collapsible`/`collapsed` pair
4382
5510
  - `attachmentsPosition: 'before'|'after' = 'after'` (attribute `attachments-position`) — places the
4383
5511
  `attachments` slot before or after the message body; both the visual and reading order follow it
5512
+ - `actionsOutsideBubble: boolean = false` (attribute `actions-outside-bubble`, reflected) — renders
5513
+ the `actions` slot's content as a sibling immediately after `[part="bubble"]` instead of nested
5514
+ inside `[part="footer"]`'s own padding/background box, for a consumer whose action row (e.g. a
5515
+ hover-reveal copy button) must sit visually outside the bubble's chrome
4384
5516
 
4385
5517
  **Events:** `lyra-retry` (no detail payload; fired by the built-in retry button, only rendered when
4386
5518
  `status="failed"`), `lyra-collapse-toggle` (`detail: boolean`, the new `collapsed` state — fired when
@@ -4396,6 +5528,8 @@ attachment chips, rendered below the message body)
4396
5528
  `attachments`, `footer` (hidden entirely when nothing is in it), `status-indicator` (a small
4397
5529
  decorative `aria-hidden` dot, absent while `status="sent"`), `status-text` (the visible text twin of
4398
5530
  `status-indicator`), `timestamp`, `retry-button` (only rendered when `status="failed"`), `actions`
5531
+ (rendered inside the footer by default; a sibling immediately after `bubble` when
5532
+ `actionsOutsideBubble` is set)
4399
5533
 
4400
5534
  **Themeable custom properties:** `--lyra-chat-message-max-width` (default `80%` — the bubble's max
4401
5535
  inline size; component-specific, no shared width token exists), plus shared tokens
@@ -5301,6 +6435,15 @@ invention (no Web Awesome equivalent).
5301
6435
  - `rowHeight: string = 'auto'` (attribute `row-height`) — `'auto'` measures each row's real height via
5302
6436
  `ResizeObserver`; a numeric string (e.g. `"56"`) fixes every row to that many pixels. Anything else
5303
6437
  (non-numeric, zero, negative, non-finite) silently falls back to `'auto'` rather than throwing.
6438
+ - `itemRole: 'listitem' | 'row' = 'listitem'` (attribute `item-role`) — `'listitem'` (default)
6439
+ preserves the plain `role="list"`/`role="listitem"` mapping with `aria-setsize`/`aria-posinset`.
6440
+ `'row'` additionally maps `[part="base"]` to `role="rowgroup"`, `[part="spacer"]` to
6441
+ `role="presentation"`, and each row to `role="row"` with `aria-rowindex` instead — for a consumer
6442
+ composing its own `role="table"` wrapper and header row around this component (see
6443
+ `lyra-dataset-viewer`).
6444
+ - `rowIndexOffset: number = 0` (attribute `row-index-offset`) — added to a row's 1-based index to
6445
+ compute `aria-rowindex` in `item-role="row"` mode (e.g. `1` when a consumer renders its own header
6446
+ row occupying `aria-rowindex="1"` outside this component). No effect in `'listitem'` mode.
5304
6447
  - `overscan: number = 6` — extra rows rendered beyond the visible viewport on each side; finite
5305
6448
  values are floored and clamped to 0–100, while non-finite values use the default 6, so an invalid
5306
6449
  runtime value cannot disable windowing and render the entire collection.
@@ -5320,6 +6463,12 @@ The package root also exports `groupByRecency(items, options?)`, a DOM-free help
5320
6463
  non-empty Today/Yesterday/Previous 7 Days/Older buckets, preserves input order within each bucket,
5321
6464
  and accepts a timestamp extractor, reference date, and label overrides.
5322
6465
 
6466
+ **Methods:** `scrollToIndex(index, options?)` — the programmatic counterpart to `active-id`'s
6467
+ automatic scroll-into-view, for a host that needs to scroll to a specific row without changing which
6468
+ row is "active." `options.align` is `'start'`, `'end'`, or `'auto'` (default — no scroll at all when
6469
+ already fully visible); `options.behavior` (default `'smooth'`) is forced to `'auto'` under
6470
+ `prefers-reduced-motion: reduce`. `index` is clamped to `0…items.length-1`.
6471
+
5323
6472
  **Events:** `lyra-load-more` (no detail — fired once per approach to the bottom of the list while
5324
6473
  `has-more` is true and `loading` is false; does not refire on every scroll tick while still near the
5325
6474
  bottom — scrolling back away from the bottom and returning, or `items` growing enough to move the
@@ -5328,10 +6477,12 @@ current visible, non-overscanned item index range — fired only when it actuall
5328
6477
 
5329
6478
  **Slots:** none — all content comes from `renderItem`.
5330
6479
 
5331
- **CSS parts:** `base` (the scrollable container, `role="list"`, `tabindex="0"`), `spacer` (the
5332
- full-content-height inner element establishing true scroll extent), `row` (one rendered row's
5333
- absolutely-positioned wrapper, `role="listitem"`), `group` (a `groups` entry's positioned
5334
- `role="heading"` marker)
6480
+ **CSS parts:** `base` (the scrollable container, `role="list"` — or `role="rowgroup"` in
6481
+ `item-role="row"` mode `tabindex="0"`), `spacer` (the full-content-height inner element
6482
+ establishing true scroll extent; `role="presentation"` in `item-role="row"` mode), `row` (one
6483
+ rendered row's absolutely-positioned wrapper, `role="listitem"` — or `role="row"` with
6484
+ `aria-rowindex` in `item-role="row"` mode), `group` (a `groups` entry's positioned `role="heading"`
6485
+ marker)
5335
6486
 
5336
6487
  **Themeable custom properties:** `--lyra-virtual-list-height` (default `24rem` — the host's bounded
5337
6488
  scroll extent; component-specific since a virtualized list is meaningless without a sized viewport),
@@ -6751,6 +7902,19 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6751
7902
  code scrolls internally past this height instead of growing the page
6752
7903
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6753
7904
  numbers for both highlighted output and the plain-text fallback
7905
+ - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
7906
+ line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
7907
+ with, and renders identically to, any `line-range` entries there.
7908
+ - `interactiveLines: boolean = false` (attribute `interactive-lines`) — turns the
7909
+ (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lyra-line-click`.
7910
+ Has no effect while `lineNumbers` is unset.
7911
+ - `highlights: LyraHighlight[] = []` (attribute: false) — host-supplied highlights to paint over the
7912
+ code (the shared anchor-target `LyraHighlight` contract from `document-viewer/anchors.ts`). Only
7913
+ `line-range` anchors are meaningful here — every other `LyraAnchor` kind is ignored.
7914
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
7915
+ entry, if any, currently treated as active (`data-active` on its lines).
7916
+ - `anchorKinds: LyraAnchor['kind'][]` — readonly `['line-range']`, for the shared anchor-target
7917
+ contract.
6754
7918
  - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — a map of language id to an
6755
7919
  already-imported shiki grammar module (e.g. `{ bash: bashGrammar }` from a module-scope
6756
7920
  `import bash from 'shiki/langs/bash.mjs'`). When `language` matches a key here, highlighting is
@@ -6762,15 +7926,26 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6762
7926
  - `languagesOnly: boolean = false` (attribute `languages-only`) — skips the default shiki loader;
6763
7927
  use when every requested language is supplied through `languages`
6764
7928
 
7929
+ **Methods:** `scrollToAnchor(target)` — resolves a `line-range` anchor (or a `highlights` id string
7930
+ resolving to one) by scrolling its start line into view within `[part="body"]`; resolves `false`
7931
+ when the anchor isn't a `line-range`, the id isn't found, or the start line is out of bounds.
7932
+
6765
7933
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6766
7934
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6767
7935
  `lyra-toggle` (`detail: { collapsed: boolean }` — fired when the built-in collapse/expand header
6768
- button is activated, same event name/shape convention as `<lyra-thinking-panel>`'s own `lyra-toggle`)
7936
+ button is activated, same event name/shape convention as `<lyra-thinking-panel>`'s own `lyra-toggle`),
7937
+ `lyra-line-click` (`detail: { line: number }` — a gutter line number was activated while
7938
+ `interactiveLines` is set), `lyra-highlight-activate` (`detail: { id: string }` — declared for
7939
+ parity with this library's other anchor-target viewers; not currently emitted by this component),
7940
+ `lyra-text-select` (`detail: { text, anchor, rects }` — a text selection inside the code body ended;
7941
+ `anchor` is a `line-range` anchor covering the selected lines)
6769
7942
 
6770
7943
  **Slots:** none.
6771
7944
 
6772
7945
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6773
- `code`
7946
+ `code`, `line-highlight` (a line marked by `highlightLines` or a `line-range` entry in `highlights`),
7947
+ `line-button` (a gutter line-number button, only rendered while `interactiveLines` and `lineNumbers`
7948
+ are both set)
6774
7949
 
6775
7950
  **Themeable custom properties:** `--lyra-code-block-max-height` (default `none` — the consumer-tunable
6776
7951
  scroll cap; only takes effect once `max-height` is set), `--lyra-code-block-font` (default
@@ -6868,19 +8043,40 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
6868
8043
  code scrolls internally past this height instead of growing the page.
6869
8044
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6870
8045
  numbers for highlighted and plain output.
8046
+ - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
8047
+ line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
8048
+ with, and renders identically to, any `line-range` entries there.
8049
+ - `interactiveLines: boolean = false` (attribute `interactive-lines`) — turns the
8050
+ (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lyra-line-click`.
8051
+ Has no effect while `lineNumbers` is unset.
8052
+ - `highlights: LyraHighlight[] = []` (attribute: false) — host-supplied highlights to paint over the
8053
+ code. Only `line-range` anchors are meaningful here — every other `LyraAnchor` kind is ignored.
8054
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
8055
+ entry, if any, currently treated as active (`data-active` on its lines).
8056
+ - `anchorKinds: LyraAnchor['kind'][]` — readonly `['line-range']`, for the shared anchor-target
8057
+ contract, identical to `<lyra-code-block>`.
6871
8058
  - `languages: Record<string, ShikiLanguageInput> = {}` (attribute: false) — grammar definitions this
6872
8059
  instance can highlight, e.g. `{ json: jsonGrammar }` (import from `shiki/langs/<name>.mjs`). Empty
6873
8060
  (the default) never highlights at all — every `language` renders the plain-text fallback.
6874
8061
 
8062
+ **Methods:** `scrollToAnchor(target)` — resolves a `line-range` anchor (or a `highlights` id string
8063
+ resolving to one) by scrolling its start line into view within `[part="body"]`; resolves `false`
8064
+ when the anchor isn't a `line-range`, the id isn't found, or the start line is out of bounds.
8065
+ Identical behavior to `<lyra-code-block>`'s own method.
8066
+
6875
8067
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6876
8068
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6877
8069
  `lyra-toggle` (`detail: { collapsed: boolean }` — fired when the built-in collapse/expand header
6878
- button is activated).
8070
+ button is activated), `lyra-line-click` (`detail: { line: number }` — a gutter line number was
8071
+ activated while `interactiveLines` is set), `lyra-highlight-activate` (`detail: { id: string }` —
8072
+ declared for parity with this library's other anchor-target viewers; not currently emitted by this
8073
+ component), `lyra-text-select` (`detail: { text, anchor, rects }` — a text selection inside the code
8074
+ body ended; `anchor` is a `line-range` anchor covering the selected lines).
6879
8075
 
6880
8076
  **Slots:** none.
6881
8077
 
6882
8078
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6883
- `code` — identical set to `<lyra-code-block>`.
8079
+ `code`, `line-highlight`, `line-button` — identical set to `<lyra-code-block>`.
6884
8080
 
6885
8081
  **Themeable custom properties:** identical to `<lyra-code-block>` — `--lyra-code-block-max-height`,
6886
8082
  `--lyra-code-block-font`, plus the same shared tokens.
@@ -6927,6 +8123,15 @@ First-party invention (no Web Awesome equivalent).
6927
8123
  all-removals diff of `oldText`.
6928
8124
  - `copyable: boolean = false` — shows a copy-to-clipboard button for the full unified-diff text.
6929
8125
  `false` (the default) renders no button.
8126
+ - `layout: 'unified' | 'split' = 'unified'` (reflected) — `'unified'` (the default) renders today's
8127
+ single interleaved `<pre>`; `'split'` renders two side-by-side `[part="side"]` columns derived from
8128
+ the same diff alignment.
8129
+ - `language: string = ''` — a shiki-recognized language id. Highlighting activates only when this
8130
+ has a matching entry in `languages` — there is deliberately no default full-table
8131
+ `lyra-code-block`-style fallback, so this component never reaches shiki's ~200-language
8132
+ dynamic-import table.
8133
+ - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — grammar definitions this
8134
+ instance can highlight, same shape as `lyra-code-block-core`'s own `languages`.
6930
8135
 
6931
8136
  **Events:** `lyra-copy` (`detail: { text: string }` — the full unified-diff text, fired on
6932
8137
  copy-button activation regardless of whether the clipboard write actually succeeded).
@@ -6934,15 +8139,19 @@ copy-button activation regardless of whether the clipboard write actually succee
6934
8139
  **Slots:** none.
6935
8140
 
6936
8141
  **CSS parts:** `base` (the root wrapper), `line` (a single line; carries
6937
- `data-type="equal"|"add"|"remove"`), `copy-button` (the copy affordance, only rendered while
6938
- `copyable`).
8142
+ `data-type="equal"|"add"|"remove"|"empty"` `"empty"` is an unbalanced-replace placeholder cell in
8143
+ `layout="split"` and never carries a `+`/`-` prefix), `copy-button` (the copy affordance, only
8144
+ rendered while `copyable`), `side` (one column in `layout="split"`, `data-side="old"|"new"`).
6939
8145
 
6940
8146
  **Themeable custom properties:** `--lyra-diff-view-font` (default `var(--lyra-font-mono)`), plus
6941
8147
  shared tokens `--lyra-color-border`/`-surface`/`-success`/`-success-quiet`/`-danger`/
6942
8148
  `-danger-quiet`/`-text`, `--lyra-radius`, `--lyra-space-xs`/`-s`, `--lyra-font-size-sm`,
6943
8149
  `--lyra-line-height-snug`, `--lyra-focus-ring-*`.
6944
8150
 
6945
- **Optional peer deps:** none.
8151
+ **Optional peer deps:** `shiki` (the same fine-grained `shiki/core`/`shiki/engine/oniguruma`/
8152
+ `shiki/wasm` subset `lyra-code-block-core` uses, never `shiki`'s full ~200-language main entry point)
8153
+ — only loaded once both `language` and a matching `languages` entry are set; unset/unmatched leaves
8154
+ the plain unhighlighted diff text untouched.
6946
8155
 
6947
8156
  ```html
6948
8157
  <lyra-diff-view copyable></lyra-diff-view>
@@ -6970,6 +8179,72 @@ consumer can compute or unit-test the same alignment without instantiating the e
6970
8179
 
6971
8180
  ---
6972
8181
 
8182
+ ## `lyra-stack-trace`
8183
+
8184
+ Parses common V8/JS-TS, Firefox/Safari, and Python stack traces into a leading message plus
8185
+ activatable frames, splitting chained/caused-by errors (`Caused by:`, `[cause]:`, Python's "direct
8186
+ cause"/"During handling" separators) into separate groups. Frames matching `internalPatterns` fold
8187
+ behind a count-labeled toggle. Falls back to verbatim raw text when nothing parses. First-party
8188
+ invention (no Web Awesome equivalent).
8189
+
8190
+ **Properties:**
8191
+ - `trace: string = ''` — the raw stack trace text to parse and render.
8192
+ - `collapseInternal: boolean = true` (attribute: `collapse-internal`) — folds runs of internal
8193
+ frames behind a toggle.
8194
+ - `internalPatterns: (string | RegExp)[] = DEFAULT_INTERNAL_PATTERNS` (attribute: false) —
8195
+ file-path substrings/`RegExp`s that mark a frame as internal.
8196
+ - `copyable: boolean = true` — shows a copy-to-clipboard button for the raw trace text.
8197
+ - `maxHeight: string = ''` (attribute: `max-height`) — caps the rendered block size and enables an
8198
+ internal scrollbar once content exceeds it (any valid CSS length). Empty string (the default)
8199
+ grows with content.
8200
+
8201
+ **Events:**
8202
+ - `lyra-frame-select` (`detail: { file?: string; line?: number; column?: number; raw: string }`) —
8203
+ a frame was activated. `column` is always undefined for Python frames, which carry no column
8204
+ information.
8205
+ - `lyra-copy` (`detail: { text: string }`) — the raw, unparsed trace text, fired on copy-button
8206
+ activation regardless of whether the clipboard write actually succeeded.
8207
+
8208
+ **Slots:** none.
8209
+
8210
+ **CSS parts:** `base` (the root wrapper; respects `max-height`), `message` (the leading error
8211
+ message text for a group), `group` (one chained-error group of frames), `frame` (a single frame
8212
+ button; carries `data-internal` for internal frames), `frame-function` (the frame's function
8213
+ name), `frame-location` (the frame's `file:line:col` text), `internal-toggle` (the collapse/expand
8214
+ toggle for a run of internal frames), `raw` (the verbatim fallback when zero structured frames
8215
+ parsed), `copy-button` (only rendered while `copyable`).
8216
+
8217
+ **Themeable custom properties:** `--lyra-stack-trace-max-height` (default `none`),
8218
+ `--lyra-stack-trace-font` (default `var(--lyra-font-mono)`), plus shared tokens
8219
+ `--lyra-color-border`/`-surface`/`-text`/`-text-quiet`/`-brand`, `--lyra-radius`,
8220
+ `--lyra-border-width-thin`, `--lyra-space-xs`/`-s`/`-2xs`, `--lyra-font-size-sm`/`-xs`,
8221
+ `--lyra-font-weight-bold`/`-semibold`, `--lyra-focus-ring-*`.
8222
+
8223
+ **Optional peer deps:** none.
8224
+
8225
+ ```html
8226
+ <lyra-stack-trace></lyra-stack-trace>
8227
+ <script type="module">
8228
+ const stackTrace = document.querySelector('lyra-stack-trace');
8229
+ stackTrace.trace = 'TypeError: boom\n at doThing (/app/src/util.js:10:5)';
8230
+ stackTrace.addEventListener('lyra-frame-select', (e) => console.log(e.detail.file, e.detail.line));
8231
+ </script>
8232
+ ```
8233
+
8234
+ The package root also exports the pure `parseStackTrace(trace: string, internalPatterns: (string |
8235
+ RegExp)[]): StackGroup[]` helper (plus `DEFAULT_INTERNAL_PATTERNS`, and the `StackFrame`/
8236
+ `StackGroup` types) — the same parsing function this component's own `willUpdate()` calls, exposed
8237
+ standalone so a consumer can parse or unit-test traces without instantiating the element at all.
8238
+
8239
+ **Known gotchas:**
8240
+ - an internal-frame run only collapses behind the `internal-toggle` when it is two or more
8241
+ consecutive internal frames; a single isolated internal frame renders as a normal `frame` button
8242
+ (there is nothing useful to fold).
8243
+ - when `trace` doesn't match any of the supported formats, `parseStackTrace()` returns `[]` and the
8244
+ component renders the text verbatim in a `raw` part instead of silently dropping content.
8245
+
8246
+ ---
8247
+
6973
8248
  ## `lyra-tool-approval-dialog`
6974
8249
 
6975
8250
  A human-in-the-loop gate: presents one proposed tool/function call (`toolName` + `args`) and blocks an
@@ -7619,8 +8894,9 @@ used" summary.
7619
8894
 
7620
8895
  **Properties:**
7621
8896
  - `segments: ContextMeterSegment[] = []` (attribute: false, JS-only) — `{ label: string; value:
7622
- number; tone?: 'brand' | 'success' | 'warning' | 'danger' | 'neutral' }[]`. `value` is an *absolute*
8897
+ number; tone?: 'brand' | 'success' | 'warning' | 'danger' | 'neutral'; color?: string }[]`. `value` is an *absolute*
7623
8898
  quantity measured against `total`, never a pre-computed percentage.
8899
+ `color`, when supplied, is a sanitized arbitrary CSS color that takes precedence over `tone`.
7624
8900
  - `total: number = 0` — the full capacity segments are measured against (e.g. a model's context
7625
8901
  window size).
7626
8902
  - `variant: 'ring' | 'bar' = 'bar'` (reflected)
@@ -7635,9 +8911,11 @@ A host `aria-label` overrides the generated meter summary and is preserved acros
7635
8911
  **Slots:** none.
7636
8912
 
7637
8913
  **CSS parts:** `base` (a `<div>` for `bar`, an `<svg>` for `ring`), `track` (the unfilled/empty
7638
- capacity), `segment` (one occupied segment — carries `data-tone` for styling), `label`
8914
+ capacity), `segment` (one occupied segment — carries `data-tone` and, for custom colors,
8915
+ `--lyra-context-meter-segment-color`), `label`
7639
8916
 
7640
- **Themeable custom properties:** no component-specific custom properties; consumes shared tokens
8917
+ **Themeable custom properties:** `--lyra-context-meter-segment-color` is set per segment when its
8918
+ `color` field is supplied; otherwise the component consumes shared tokens
7641
8919
  `--lyra-space-xs`, `--lyra-color-text-quiet`, `--lyra-font`, `--lyra-radius`, `--lyra-color-border`,
7642
8920
  `--lyra-color-surface` (the bar variant's inter-segment seam), `--lyra-color-brand`,
7643
8921
  `--lyra-color-success`, `--lyra-color-warning`, `--lyra-color-danger`, `--lyra-transition-base`.
@@ -7840,6 +9118,20 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7840
9118
  - `maxHeight: string = ''` (attribute `max-height`) — a CSS length (e.g. `"24rem"`); once set,
7841
9119
  `[part="body"]` scrolls internally past this height instead of growing the page — same contract as
7842
9120
  `lyra-json-viewer`'s identically-named prop.
9121
+ - `zoomable: boolean = false` (reflected) — wraps the rendered image (image format only) in an
9122
+ internal `<lyra-zoomable-frame>`. `false` (the default) preserves the exact pre-`zoomable` DOM — an
9123
+ inline thumbnail (e.g. in a chat stream) must not unexpectedly grow a focusable zoom-chrome
9124
+ viewport; an inspection surface opts in.
9125
+ - `highlights: LyraHighlight[] = []` (attribute: false) — display-only `region` highlights painted
9126
+ over the image-format preview; ignored for the `text`/`generic` formats.
9127
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
9128
+ entry, if any, currently treated as active (`data-active` on its `region-highlight`).
9129
+ - `anchorKinds` is a readonly `['region']` (this viewer's supported `LyraAnchor.kind` values for the
9130
+ shared anchor-target contract).
9131
+
9132
+ **Methods:** `scrollToAnchor(target)` — scrolls a `region` highlight (by id, or a `LyraAnchor`
9133
+ matched back to its owning `LyraHighlight` by reference) into view; resolves `false` when nothing
9134
+ matches, the anchor isn't `region`, or the format isn't currently `image`.
7843
9135
 
7844
9136
  **Events:**
7845
9137
  - `lyra-download` — `detail: { src, filename }` — fired when the generic-download fallback's link is
@@ -7848,6 +9140,8 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7848
9140
  - `lyra-render-error` — `detail: { error }` — fired when this component's own `text/*`/
7849
9141
  `application/json` `fetch(src)` fails (network error or non-2xx response). Distinct from
7850
9142
  `status="error"`, which is entirely host-driven.
9143
+ - `lyra-highlight-activate` — `detail: { id }` — a region highlight was clicked or activated via
9144
+ Enter/Space (image format only).
7851
9145
 
7852
9146
  **Slots:** `unsupported` — escape hatch: when populated, its content renders *instead of* the generic
7853
9147
  download fallback for any `mime-type` this component doesn't natively support. Ignored while
@@ -7858,7 +9152,11 @@ download fallback for any `mime-type` this component doesn't natively support. I
7858
9152
  used both for `status="converting"` and this component's own in-flight text fetch), `error`
7859
9153
  (`role="alert"` — used both for `status="error"` and a failed text fetch), `download-link` (only
7860
9154
  rendered when `src` is set *and* passes the link-safe scheme allowlist — see the URL-safety note
7861
- above; excludes `data:` even though the other two sinks allow it)
9155
+ above; excludes `data:` even though the other two sinks allow it), `highlight-layer` (wrapper around
9156
+ every rendered region highlight, image format only), `region-highlight` (one region highlight,
9157
+ `data-tone`, `data-active`; image format only), `frame-viewport`/`frame-content`/`frame-controls`/
9158
+ `frame-zoom-in`/`frame-zoom-out`/`frame-reset` (forwarded from the internal `<lyra-zoomable-frame>`
9159
+ while `zoomable`; image format only)
7862
9160
 
7863
9161
  **Themeable custom properties:** `--lyra-document-preview-max-height` (default `none`) — the
7864
9162
  consumer-tunable scroll cap on `[part="body"]`, set from `max-height`; `none` means the preview grows
@@ -7943,6 +9241,13 @@ type. First-party invention.
7943
9241
  - `src: string = ''` — source URL passed to the selected renderer or the fallback preview.
7944
9242
  - `registry?: DocumentRendererRegistry` (attribute: false) — optional per-instance registry override;
7945
9243
  the module-level registry is used when unset.
9244
+ - `alt: string = ''` — media alt text forwarded to the resolved renderer, for image-like renderers.
9245
+ - `anchor: LyraAnchor | string | null = null` (attribute: false) — declarative scroll-to-anchor
9246
+ target forwarded to the resolved renderer; a string is a highlight id in `highlights`.
9247
+ `hasChanged: () => true`, so re-assigning the same value (e.g. re-clicking the same citation
9248
+ badge) still re-fires.
9249
+ - `highlights: LyraHighlight[] = []` (attribute: false) — highlights forwarded to the resolved
9250
+ renderer.
7946
9251
 
7947
9252
  **Events:**
7948
9253
  - `lyra-close` — `detail: DocumentViewerCloseReason`, the nested dialog's dismissal reason. The
@@ -7994,13 +9299,33 @@ Mammoth preserves document structure such as headings, paragraphs, lists, tables
7994
9299
  not intended to reproduce pixel-exact Word page layout. There is no unsanitized rendering escape
7995
9300
  hatch: if `dompurify` is unavailable, rendering is blocked even when Mammoth converted successfully.
7996
9301
 
9302
+ Every rendered heading's slug (the same GitHub-slugger-style algorithm `<lyra-markdown>` uses) is
9303
+ stamped as its `id` and cached into `getHeadingTree()`'s document-ordered outline. Adopts
9304
+ `DocumentAnchorTarget`: `fragment` anchors resolve against that outline, `text-quote` anchors via
9305
+ the shared quote-scoping helpers; `highlights` re-resolve by quote after every render.
9306
+
7997
9307
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
7998
- the scrollable document body.
9308
+ the scrollable document body. `anchorKinds` is a readonly `['fragment', 'text-quote']` (this
9309
+ viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
9310
+
9311
+ **Methods:** `getHeadingTree()` returns the document-ordered outline as `DocxHeadingItem[]` (`{ id,
9312
+ label, level }`), cached on every successful load. `search(query)` resolves the match count via a
9313
+ case-insensitive substring search over the rendered content's text (empty/whitespace query behaves
9314
+ like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches
9315
+ (wrapping, resolving `false` when there are none); `clearSearch()` clears the query, matches, and
9316
+ painted marks.
7999
9317
 
8000
9318
  **Events:** `lyra-render-error` with `detail.error` when fetching, conversion, sanitization, or a
8001
- non-fatal Mammoth conversion message occurs.
9319
+ non-fatal Mammoth conversion message occurs. `lyra-search-change` (`detail: { query, matchCount,
9320
+ activeIndex }`) — from `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
9321
+ `lyra-highlight-activate` (`detail: { id }`) — a painted `text-quote` highlight was clicked.
9322
+ `lyra-text-select` (`detail: { text, anchor, rects }`) — fired on selection end inside the rendered
9323
+ content. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9324
+ `scrollToAnchor()` call.
8002
9325
 
8003
- **CSS parts:** `base`, `body`, `content`, `spinner`, and `error`.
9326
+ **CSS parts:** `base`, `body`, `content`, `spinner`, `error`, `highlight` (a painted `text-quote`
9327
+ highlight), `search-match` (a painted in-document search match), and `search-match-active` (the
9328
+ currently active search match, also carries `search-match`).
8004
9329
 
8005
9330
  **Optional peer dependencies:** install `mammoth` and `dompurify` with `pnpm add mammoth dompurify`.
8006
9331
  The component registers an eager `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
@@ -8025,13 +9350,17 @@ remain available without DOMPurify. Attachments are listed as filename and size
8025
9350
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
8026
9351
  `documentPreviewResourceTooLarge` message instead of the message.
8027
9352
 
8028
- **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings.
9353
+ **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `foldQuotes:
9354
+ boolean = false` (attribute `fold-quotes`) — collapses trailing quoted-reply text/HTML behind a
9355
+ localized show/hide toggle. `false` (the default) preserves the full body rendering.
8029
9356
 
8030
9357
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
8031
9358
 
8032
9359
  **CSS parts:** `base`, `headers`, `from-label`, `from`, `to-label`, `to`, `subject-label`, `subject`,
8033
9360
  `date-label`, `date`, `body`, `body-html`, `body-text`, `attachments`, `attachments-label`,
8034
- `attachment-list`, `attachment-item`, `spinner`, and `error`.
9361
+ `attachment-list`, `attachment-item`, `quoted` (a folded quoted-text block, hidden until expanded, only
9362
+ while `foldQuotes`), `quote-toggle` (the show/hide-quoted-text toggle button, only while `foldQuotes`),
9363
+ `spinner`, and `error`.
8035
9364
 
8036
9365
  **Optional peer dependencies:** install `postal-mime` and `dompurify` with
8037
9366
  `pnpm add postal-mime dompurify`. The component registers `message/rfc822` and falls back to
@@ -8087,19 +9416,48 @@ epub.js renders the reading area into its stable `mount` element, using an inter
8087
9416
  chapter content.
8088
9417
 
8089
9418
  **Properties:** `src` and `name` are strings. `accessibleLabel` (attribute `aria-label`) overrides
8090
- the reading region's accessible name.
8091
-
8092
- **Events:** `lyra-render-error` with `detail.error` when fetching, opening, or rendering fails.
9419
+ the reading region's accessible name. `location: string = ''` (not reflected — CFIs are long) is
9420
+ a CFI or spine href identifying the current reading position: set before the book finishes
9421
+ loading it's recorded and applied once ready, set after it applies immediately, and epub.js's own
9422
+ `relocated` event keeps it in sync with user navigation without re-triggering its own `display()`
9423
+ call. `anchorKinds` is a readonly `['cfi', 'text-quote']` (this viewer's supported `LyraAnchor.kind`
9424
+ values for the shared anchor-target contract).
9425
+
9426
+ **Methods:** `getToc()` resolves the EPUB's own navigation document (`book.navigation.toc`,
9427
+ populated once `book.ready` resolves) flattened into document-ordered `EbookTocItem[]` (`{ id,
9428
+ label, href, level }`, `level` starting at 1 for a top-level entry, `id` falling back to `href`
9429
+ when a navigation entry has none), `[]` before a book has loaded. `search(query)` resolves the
9430
+ match count across every spine section, in document order, via epub.js's own `item.load()`/
9431
+ `item.find()`/`item.unload()` (empty/whitespace query behaves like `clearSearch()`; a newer
9432
+ `search()` call or a `src` change aborts an in-flight scan); `searchNext()`/`searchPrevious()`
9433
+ advance/step back through matches (wrapping, resolving `false` when there are none); `clearSearch()`
9434
+ clears the query, matches, and painted search annotation.
9435
+
9436
+ **Events:** `lyra-render-error` with `detail.error` when fetching, opening, or rendering fails;
9437
+ `lyra-location-change` (`detail: { cfi, href }`) fired from epub.js's own `relocated` event;
9438
+ `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) from `search()`/`searchNext()`/
9439
+ `searchPrevious()`/`clearSearch()`.
8093
9440
 
8094
9441
  **CSS parts:** `base`, `toolbar`, `previous-button`, `next-button`, `previous-icon`, `next-icon`,
8095
- `mount`, and `error`.
9442
+ `mount`, `error`, and `announcer` (the visually-hidden `role="status"` region search results
9443
+ announce through).
8096
9444
 
8097
9445
  **Optional peer dependency:** install `epubjs` with `pnpm add epubjs`. The document-viewer registry
8098
- matches `application/epub+zip` and `.epub` filenames.
9446
+ matches `application/epub+zip` and `.epub` filenames, declaring `{ anchors: ['cfi', 'text-quote'],
9447
+ search: true, textSelect: true }` capabilities.
8099
9448
 
8100
9449
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
8101
9450
  `documentPreviewResourceTooLarge` message instead of the ebook.
8102
9451
 
9452
+ Adopts the shared anchor-target contract (`highlights`, `activeHighlightId`, `scrollToAnchor()`,
9453
+ events `lyra-highlight-activate`/`lyra-text-select`/`lyra-anchor-result`): a `cfi` anchor displays
9454
+ directly via `rendition.display()`; a `text-quote` anchor resolves by scanning the spine with
9455
+ epub.js's own `item.find()`, since chapter content lives inside epub.js-owned iframes rather than
9456
+ this component's own shadow DOM — `lyra-text-select` mirrors epub.js's own `selected` event for the
9457
+ same reason. `highlights` (kind `cfi`) paint via `rendition.annotations.highlight()` and are
9458
+ re-applied whenever the rendition is recreated (a `src` change, or a reconnect remount), since
9459
+ epub.js doesn't persist annotations across a fresh `renderTo()`.
9460
+
8103
9461
  ## `lyra-pptx-viewer`
8104
9462
 
8105
9463
  Best-effort client-side PPTX viewer backed by the optional `@aiden0z/pptx-renderer` peer. A
@@ -8149,11 +9507,28 @@ MIME type. Unknown values return a generic file result.
8149
9507
  Fetches an SVG document, sanitizes it with the optional `dompurify` peer, and renders it inline.
8150
9508
 
8151
9509
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
8152
- the scrollable body.
9510
+ the scrollable body. `zoomable: boolean = false` (reflected) — wraps the rendered content in an
9511
+ internal `<lyra-zoomable-frame>`. `false` (the default) preserves the exact pre-`zoomable` DOM — an
9512
+ inline thumbnail (e.g. in a chat stream) must not unexpectedly grow a focusable zoom-chrome viewport;
9513
+ an inspection surface opts in. `highlights: LyraHighlight[] = []` (attribute: false) — display-only
9514
+ `region` highlights painted over the rendered SVG. `activeHighlightId: string | null = null`
9515
+ (attribute `active-highlight-id`) — the `highlights` entry, if any, currently treated as active
9516
+ (`data-active` on its `region-highlight`). `anchorKinds` is a readonly `['region']` (this viewer's
9517
+ supported `LyraAnchor.kind` values for the shared anchor-target contract).
9518
+
9519
+ **Methods:** `scrollToAnchor(target)` — scrolls a `region` highlight (by id, or a `LyraAnchor` matched
9520
+ back to its owning `LyraHighlight` by reference) into view; resolves `false` when nothing matches, the
9521
+ anchor isn't `region`, or the document isn't loaded yet (no retry loop — a caller invoking this before
9522
+ `src` resolves simply gets `false`).
8153
9523
 
8154
9524
  **Events:** `lyra-render-error` with `detail.error` when fetching or sanitizing fails.
9525
+ `lyra-highlight-activate` (`detail: { id }`) — a region highlight was clicked or activated via
9526
+ Enter/Space.
8155
9527
 
8156
- **CSS parts:** `base`, `body`, `svg`, `spinner`, and `error`.
9528
+ **CSS parts:** `base`, `body`, `svg`, `spinner`, `error`, `highlight-layer` (wrapper around every
9529
+ rendered region highlight), `region-highlight` (one region highlight, `data-tone`, `data-active`),
9530
+ `frame-viewport`/`frame-content`/`frame-controls`/`frame-zoom-in`/`frame-zoom-out`/`frame-reset`
9531
+ (forwarded from the internal `<lyra-zoomable-frame>` while `zoomable`).
8157
9532
 
8158
9533
  **Optional peer dependency:** `dompurify`.
8159
9534
 
@@ -8178,23 +9553,44 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8178
9553
 
8179
9554
  ## `lyra-dataset-viewer`
8180
9555
 
8181
- Fetches tab-, pipe-, or delimiter-separated text and renders an accessible table using the optional
8182
- `papaparse` peer. The document registry matches `.tsv`, `.psv`, and `.dat` filenames.
9556
+ Fetches tab-, pipe-, or delimiter-separated text and renders a virtualized, accessible table (a
9557
+ `role="table"` container with a sticky `role="row"` header, composed with `<lyra-virtual-list
9558
+ item-role="row">` for the body) using the optional `papaparse` peer. The document registry matches
9559
+ `.tsv`, `.psv`, and `.dat` filenames.
8183
9560
 
8184
- **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings.
9561
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with the
9562
+ header row always occupying row 1 (this component always parses with a header row, so the first row
9563
+ is never part of the virtualized body); `scrollToAnchor()` scrolls the addressed row into view via
9564
+ the virtualized list's `active-id`. `highlights` paint as a `part="cell-highlight"` cell wrapping a
9565
+ focusable `part="cell-highlight-action"` native button, keeping the ARIA table tree intact.
9566
+
9567
+ **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `anchorKinds` is
9568
+ a readonly `['cell-range']` (this viewer's supported `LyraAnchor.kind` values for the shared
9569
+ anchor-target contract).
9570
+
9571
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring search over
9572
+ every body cell's raw string value, ordered row then column (empty/whitespace query behaves like
9573
+ `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches (wrapping,
9574
+ resolving `false` when there are none); `clearSearch()` clears the query, matches, and cursor.
8185
9575
 
8186
9576
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
9577
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9578
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9579
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9580
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8187
9581
 
8188
- **CSS parts:** `base`, `body`, `table`, `spinner`, and `error`.
9582
+ **CSS parts:** `base`, `body`, `table`, `header-row`, `header-cell`, `data-row`, `cell`,
9583
+ `cell-highlight` (a `role="cell"` covered by a `highlights` entry; wraps the action button),
9584
+ `cell-highlight-action` (the native button filling a highlighted cell — focusable, emits
9585
+ `lyra-highlight-activate` on click or Enter/Space), `spinner`, and `error`.
8189
9586
 
8190
9587
  **Exports:** `DatasetTable` is `{ fields: string[]; rows: Record<string, string>[] }`.
8191
9588
 
8192
9589
  **Optional peer dependency:** `papaparse`.
8193
9590
 
8194
- Remote resources are capped at 25 MB, and the parsed table at 1,000 rows and 1,000 columns (lower
8195
- than `lyra-csv-viewer`/`lyra-spreadsheet-viewer`'s shared 10,000-row cap, since this component renders
8196
- every row into a real, non-virtualized `<table>` in one synchronous pass); exceeding any of these
8197
- surfaces the localized `documentPreviewResourceTooLarge` message instead of the table.
9591
+ Remote resources are capped at 25 MB, and the parsed table at 10,000 rows and 1,000 columns (the
9592
+ same shared default as `lyra-csv-viewer`/`lyra-spreadsheet-viewer`); exceeding either surfaces the
9593
+ localized `documentPreviewResourceTooLarge` message instead of the table.
8198
9594
 
8199
9595
  ## `lyra-contact-viewer`
8200
9596
 
@@ -8222,13 +9618,23 @@ Fetches a PDF and renders its pages with the optional `pdfjs-dist` peer. Pages a
8222
9618
  `lyra-virtual-list`, and PDF.js's selectable text layer is positioned over each rendered canvas.
8223
9619
 
8224
9620
  **Properties:** `src` and `name` are strings. `page: number = 1` is the one-based current page and
8225
- `zoom: number = 1` is clamped to `0.25`–`4`.
9621
+ `zoom: number = 1` is clamped to `0.25`–`4`. `anchorKinds` is a readonly `['page', 'text-quote',
9622
+ 'region']` (this viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
8226
9623
 
8227
9624
  **Events:** `lyra-render-error` with `detail.error` when fetching, parsing, or rendering fails;
8228
9625
  `lyra-page-change` with `{ page, pageCount }`; and `lyra-zoom-change` with `{ zoom }`.
8229
9626
 
8230
9627
  **Methods:** `nextPage()`, `previousPage()`, `zoomIn()`, and `zoomOut()` update the corresponding
8231
- controlled state within its supported range.
9628
+ controlled state within its supported range. `getPageText(page)` resolves the raw reading-order text
9629
+ of one page (per-page LRU-cached, 64 pages), rejecting on no loaded document or an out-of-range page.
9630
+ `renderPageThumbnail(page, canvas, options?)` renders `page` into a caller-owned `canvas` at
9631
+ `options.width` CSS px (default 96), devicePixelRatio-aware, resolving `false` when not ready or out
9632
+ of range. `goToPage(page)` scrolls the virtualized list to `page`, resolving `true` once mounted (or
9633
+ `false` for an out-of-range value, without changing `page`). `getOutline()` resolves the document's
9634
+ table of contents as `PdfOutlineItem[]` (`{ title, page?, children? }`), `[]` when there is none.
9635
+ `search(query)` resolves the match count across all pages (empty/whitespace query behaves like
9636
+ `clearSearch()`); `searchNext()` and `searchPrevious()` advance/step back through matches (wrapping,
9637
+ resolving `false` when there are none); `clearSearch()` clears the query, matches, and painted marks.
8232
9638
 
8233
9639
  **CSS parts:** `base`, `toolbar`, `page-indicator`, `zoom-indicator`, `pages`, `page`, `text-layer`,
8234
9640
  `spinner`, and `error`.
@@ -8245,14 +9651,31 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8245
9651
  Fetches and renders `.xlsx` and `.xls` workbooks with the optional `xlsx` (SheetJS) peer. Multiple
8246
9652
  worksheets render through a `<lyra-tabs>` switcher, and body rows use `<lyra-virtual-list>`.
8247
9653
 
8248
- **Properties:** `src` and `name` are strings.
9654
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses one sheet's raw grid, 1-based, with
9655
+ its header row included, resolving the target sheet from the anchor's own `sheet` field (falling
9656
+ back to a `Sheet!`-prefixed `range`, then the active sheet); `scrollToAnchor()` switches
9657
+ `<lyra-tabs>`'s active tab first when needed, then scrolls the addressed row/column into view.
9658
+ `highlights` paint as a focusable `part="cell-highlight"`.
9659
+
9660
+ **Properties:** `src` and `name` are strings. `anchorKinds` is a readonly `['cell-range']` (this
9661
+ viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
9662
+
9663
+ **Methods:** `search(query)` resolves the match count across every sheet's stringified cell values,
9664
+ ordered sheet then row then column, switching tabs as navigation crosses sheets (empty/whitespace
9665
+ query behaves like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through
9666
+ matches (wrapping, resolving `false` when there are none); `clearSearch()` clears the query,
9667
+ matches, and painted marks.
8249
9668
 
8250
9669
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
9670
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9671
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9672
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9673
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8251
9674
 
8252
- **CSS parts:** `base`, `tabs`, `sheet`, `header-row`, `data-row`, `cell`, `rows`, `spinner`, and
8253
- `error`.
9675
+ **CSS parts:** `base`, `tabs`, `sheet`, `header-row`, `data-row`, `cell`, `cell-highlight` (a cell
9676
+ covered by a `highlights` entry), `rows`, `spinner`, and `error`.
8254
9677
 
8255
- **Optional peer dependency:** install `xlsx` with `pnpm add xlsx`. The registry matches the official
9678
+ **Optional peer dependency:** install `xlsx` with `pnpm add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz`. The official CDN matches the
8256
9679
  `.xlsx` and `.xls` MIME types and filename extensions.
8257
9680
 
8258
9681
  Remote resources are capped at 25 MB, and each parsed sheet at 10,000 rows and 1,000 columns;
@@ -8263,12 +9686,30 @@ the workbook.
8263
9686
 
8264
9687
  Fetches CSV text, parses quoted fields with the optional `papaparse` peer, and virtualizes body rows.
8265
9688
 
9689
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with the
9690
+ header row included whenever `has-header-row` is set; `scrollToAnchor()` scrolls the addressed
9691
+ row/column into view via the virtualized list's `active-id`. `highlights` paint as a focusable
9692
+ `part="cell-highlight"`.
9693
+
8266
9694
  **Properties:** `src` and `name` are strings. `hasHeaderRow: boolean = true` (attribute
8267
9695
  `has-header-row`) controls whether the first parsed row is rendered as a sticky header.
9696
+ `anchorKinds` is a readonly `['cell-range']` (this viewer's supported `LyraAnchor.kind` values for
9697
+ the shared anchor-target contract).
9698
+
9699
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring match over
9700
+ the same stringified cell values `cell()` renders, ordered row then column (empty/whitespace query
9701
+ behaves like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches
9702
+ (wrapping, resolving `false` when there are none); `clearSearch()` clears the query, matches, and
9703
+ painted marks.
8268
9704
 
8269
9705
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing reports an error.
9706
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9707
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9708
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9709
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8270
9710
 
8271
- **CSS parts:** `base`, `sheet`, `header-row`, `data-row`, `cell`, `rows`, `spinner`, and `error`.
9711
+ **CSS parts:** `base`, `sheet`, `header-row`, `data-row`, `cell`, `cell-highlight` (a cell covered by
9712
+ a `highlights` entry), `rows`, `spinner`, and `error`.
8272
9713
 
8273
9714
  **Optional peer dependency:** install `papaparse` with `pnpm add papaparse`. The registry matches
8274
9715
  `text/csv` and `.csv` filenames.
@@ -8946,6 +10387,41 @@ Groups avatars and collapses excess members into a localized overflow indicator.
8946
10387
  `max`, `shape`, `size`, and `tone`. The default slot accepts avatar elements. **CSS parts:** `base`,
8947
10388
  `avatars`, and `overflow`.
8948
10389
 
10390
+ ## `lyra-emoji-picker`
10391
+
10392
+ A searchable, keyboard-navigable, form-associated emoji picker. `groups` is fully consumer-suppliable
10393
+ — the component ships no emoji data of its own — in the same "zero/optional-peer dependency" spirit
10394
+ as `<lyra-lite-chart>`/`<lyra-heatmap>`; an optional convenience auto-loader fetches a default set on
10395
+ connect from the `emoji-picker-element-data` peer, but only when `groups` hasn't already been
10396
+ supplied (an explicit empty array still counts as supplied and skips the auto-load).
10397
+
10398
+ **Properties:** the shared form properties `name`, `value`, `disabled`, and `required`, plus
10399
+ `groups: EmojiPickerGroup[] = []` (attribute: false) — `EmojiPickerGroup { key, label, emojis:
10400
+ EmojiPickerItem[] }`, `EmojiPickerItem { emoji, name, shortcodes? }`; the search field matches `name`
10401
+ and every `shortcodes` entry, case-insensitively. Empty (the default, before the auto-loader
10402
+ resolves) renders just the search input and the empty state. `accessibleLabel` (`aria-label`)
10403
+ forwards a host-supplied accessible name to the internal `role="listbox"` grid; empty falls back to
10404
+ the localized default grid label.
10405
+
10406
+ **Events:** `lyra-change` with `detail: { emoji }` (an emoji was picked — click, or Enter/Space on
10407
+ the active grid cell; also sets `value`), plus the shared form `input`, `change`, `focus`, and `blur`.
10408
+
10409
+ **Keyboard:** the grid is a roving-tabindex listbox (a single Tab stop — only the active emoji is
10410
+ tabbable). ArrowLeft/ArrowRight step the active item backward/forward following reading direction
10411
+ (swapped under RTL), ArrowUp/ArrowDown move by one visual row (measured from the live wrap layout),
10412
+ Home/End jump to the first/last item, and Enter/Space picks the active item. The search input is a
10413
+ `role="combobox"` over the same listbox: the arrow keys and Enter also work while focus stays in
10414
+ the input, with `aria-activedescendant` tracking the active option. Hovering an emoji with the
10415
+ pointer also moves the active item to it.
10416
+
10417
+ **CSS parts:** `base`, `search` (`role="combobox"`), `grid` (`role="listbox"`), `group-label`,
10418
+ `emoji` (each emoji's own `role="option"` button), `empty` (shown when the search matches nothing).
10419
+
10420
+ **Optional peer dependency:** install `emoji-picker-element-data` with
10421
+ `pnpm add emoji-picker-element-data` for the built-in auto-loaded default emoji set — omit it and
10422
+ supply `groups` directly instead. The loader never throws; a missing or failed peer logs one
10423
+ `console.warn` and simply leaves `groups` empty.
10424
+
8949
10425
  ## `lyra-include`
8950
10426
 
8951
10427
  Loads HTML or text from `src` into the component. **Properties:** `src` and `mode` (`html` or `text`).
@@ -9054,3 +10530,1139 @@ These apply across the whole library rather than to any one component:
9054
10530
  - **RTL.** Components generally rely on CSS logical properties to flip layout for free; `lyra-split`
9055
10531
  and `lyra-time-range` additionally consult `internal/rtl.ts`'s `isRtl()` to mirror the physical
9056
10532
  drag-direction/arrow-key math that logical properties alone don't cover.
10533
+
10534
+ ## `lyra-audio-visualizer`
10535
+
10536
+ A presentational, canvas-drawn voice-activity visualization (bars or waveform) — the
10537
+ LiveKit-BarVisualizer counterpart for this library. Driven by a `MediaStream` (lazily wired to a
10538
+ WebAudio `AnalyserNode`), a numeric `level` for hosts that already compute levels (e.g.
10539
+ `<lyra-push-to-talk>`'s `lyra-level`), or `state` alone for an ambient animation when no real signal
10540
+ exists. A real signal (`stream` or `level`) always drives amplitude regardless of
10541
+ `prefers-reduced-motion`; only the signal-less ambient animation is throttled under reduced motion.
10542
+
10543
+ **Properties:** `stream: MediaStream | null = null` (attribute: false), `level: number | null = null`,
10544
+ `state: 'idle' | 'listening' | 'thinking' | 'speaking' = 'idle'` (reflected), `variant: 'bars' |
10545
+ 'waveform' = 'bars'` (reflected), `barCount: number = 5` (attribute `bar-count`), `gain: number = 1`,
10546
+ and `label: string = ''`.
10547
+
10548
+ **Methods:** `refreshTheme()` re-reads themeable custom properties after a runtime theme change.
10549
+
10550
+ **CSS parts:** `base` (the root wrapper) and `canvas` (the drawing surface, `aria-hidden`; the host
10551
+ itself carries `role="img"` and the accessible name).
10552
+
10553
+ **Themeable custom properties:** `--lyra-audio-visualizer-color` (default `--lyra-color-brand` —
10554
+ active bar/waveform color) and `--lyra-audio-visualizer-quiet-color` (default
10555
+ `--lyra-color-brand-quiet` — inactive/idle color).
10556
+
10557
+ ## `lyra-branch-picker`
10558
+
10559
+ The "‹ 2 / 5 ›" navigator across regenerated/edited variants of one message. Pure controlled: it
10560
+ never mutates its own `index` — the same contract `<lyra-pagination>` already establishes for
10561
+ `page`. The host listens for `lyra-branch-change`, swaps the displayed branch content, and applies
10562
+ the new `index` back. Renders nothing at all while `count < 2`, so a host can bind it unconditionally
10563
+ on every message regardless of whether that message actually has multiple branches yet.
10564
+
10565
+ **Properties:** `index: number = 0` (reflected) and `count: number = 1` (reflected) — the current
10566
+ 0-based branch and the total branch count. `label: string = ''`.
10567
+
10568
+ **Methods:** `focus()` and `blur()` forward to the group wrapper.
10569
+
10570
+ **Events:** `lyra-branch-change` — a branch navigation was requested. `detail: { index }`, always a
10571
+ valid target (never past either bound); the consumer applies `index` after switching the displayed
10572
+ branch content.
10573
+
10574
+ **CSS parts:** `base` (the group wrapper, `role="group"`), `previous-button`, `next-button`, and
10575
+ `position` (the visible "2 / 5" text).
10576
+
10577
+ ## `lyra-compare-panel`
10578
+
10579
+ Side-by-side A/B output comparison with a winner vote (LMSYS-arena / LangSmith-pairwise style): two
10580
+ slotted panes, a vote bar, synchronized reading.
10581
+
10582
+ **Properties:** `labelA: string = ''` (attribute `label-a`) and `labelB: string = ''` (attribute
10583
+ `label-b`) — pane headings. `vote: 'a' | 'b' | 'tie' | 'both-bad' | null = null` (reflected) — the
10584
+ recorded winner, host-writable to reflect a previously-recorded vote back. `itemId: string = ''`
10585
+ (attribute `item-id`) — an opaque id round-tripped through `lyra-vote`. `hideTie: boolean = false`
10586
+ (attribute `hide-tie`) and `hideBothBad: boolean = false` (attribute `hide-both-bad`) hide the
10587
+ corresponding vote button. `syncScroll: boolean = false` (attribute `sync-scroll`) links both panes'
10588
+ scroll position.
10589
+
10590
+ **Slots:** `a` (the first output — any content, a chat message, markdown, a viewer), `b` (the second
10591
+ output), and `prompt` (optional shared-input header above both panes).
10592
+
10593
+ **Events:** `lyra-vote` — `detail: { choice, itemId }`.
10594
+
10595
+ **CSS parts:** `base` (the outer wrapper), `prompt` (the optional prompt header, hidden when the
10596
+ `prompt` slot is empty), `panes` (the row, or under 640px column, wrapping both panes), `pane-a`,
10597
+ `pane-b` (each pane's labeled scroll region), `pane-header` (a pane's visible heading), `vote-bar`
10598
+ (the `role="group"` row of vote buttons), `vote-button` (one vote button), and `live-region` (the
10599
+ internal vote-announcement live region).
10600
+
10601
+ ## `lyra-highlight-layer`
10602
+
10603
+ A presentational overlay that paints highlight rectangles (percent-of-box coordinates) over
10604
+ positioned content and owns their activation, active/flash styling, and keyboard access. `items`
10605
+ order is the caller's own reading order; the layer does not re-sort geometrically. Fills its nearest
10606
+ positioned ancestor.
10607
+
10608
+ **Properties:** `items: HighlightLayerItem[] = []` (attribute: false), `activeId: string | null =
10609
+ null` (attribute `active-id`), and `interactive: boolean = true` (reflected) — gates click/keyboard
10610
+ activation.
10611
+
10612
+ **Methods:** `flash(id)` briefly re-triggers the flash styling for an already-rendered rect (e.g. a
10613
+ re-click of the same source citation).
10614
+
10615
+ **Events:** `lyra-highlight-activate` — a rect was activated (click, or Enter/Space while focused).
10616
+ `detail: { id }`.
10617
+
10618
+ **CSS parts:** `base` (the absolutely-positioned overlay, inset 0) and `rect` (one highlight
10619
+ rectangle; carries `data-tone`/`data-active`/`data-flash` state attributes).
10620
+
10621
+ ## `lyra-message-actions`
10622
+
10623
+ The per-message action toolbar for `lyra-chat-message`'s `actions` slot: opt-in built-ins (copy /
10624
+ regenerate / edit / feedback) that emit intent events, plus a default slot for custom controls (e.g.
10625
+ a slotted `lyra-branch-picker`). `role="toolbar"` with WAI-ARIA APG roving-tabindex; ArrowLeft/
10626
+ ArrowRight (RTL-aware) plus Home/End move focus across every stop — built-ins and slotted controls
10627
+ alike — via `.focus()`. Only the plain-button built-ins (`regenerate`/`edit`) get their `tabindex`
10628
+ toggled by this component itself; a composite child (`lyra-copy-button`, the `feedback` built-in, any
10629
+ slotted custom element) remains independently reachable via the page's native Tab order alongside the
10630
+ toolbar's single roving stop, since a shadow-root-internal focusable element can't be suppressed from
10631
+ outside its own component.
10632
+
10633
+ **Properties:** `controls: MessageActionControl[] = []` (attribute: false, each `'copy' |
10634
+ 'regenerate' | 'edit' | 'feedback'`) — which built-ins render, in that order. `copyText: string = ''`
10635
+ (attribute `copy-text`) — required for the `copy` built-in to render at all. `feedbackValue: 'up' |
10636
+ 'down' | null = null` (attribute `feedback-value`) — forwarded to the embedded, thumbs-only
10637
+ `lyra-message-feedback` (its `reasons`/`commentable`/`detailFor` are never forwarded, so its detail
10638
+ panel never opens). `revealOnHover: boolean = false` (reflected, attribute `reveal-on-hover`) — hides
10639
+ the bar until the closest `lyra-chat-message` ancestor is hovered or a control inside has focus.
10640
+ `label: string = ''` — accessible name override for the toolbar. `accessibleLabel: string | null =
10641
+ null` (attribute `aria-label`) — overrides the toolbar's computed accessible name, winning over
10642
+ `label` and the localized default; attribute-reflects from a host-level `aria-label`.
10643
+
10644
+ **Events:** `lyra-regenerate`/`lyra-edit` — a built-in was activated, no detail. `lyra-copy` —
10645
+ `detail: { text }`, surfaced by the embedded `lyra-copy-button` (bubbles/composed already, not
10646
+ re-emitted). `lyra-change`/`lyra-submit` — bubble unchanged from the embedded, thumbs-only
10647
+ `lyra-message-feedback`.
10648
+
10649
+ **Slots:** default — additional controls (e.g. `lyra-copy-button`, `lyra-icon-button`,
10650
+ `lyra-branch-picker`) appended after the built-ins; they participate in the toolbar's arrow-key
10651
+ navigation.
10652
+
10653
+ **CSS parts:** `base` (the toolbar, `role="toolbar"`), `copy-button` (the embedded
10654
+ `lyra-copy-button`), `regenerate-button`, `edit-button`, and `feedback` (the embedded
10655
+ `lyra-message-feedback`).
10656
+
10657
+ ## `lyra-message-feedback`
10658
+
10659
+ Thumbs up/down for one assistant message, with an optional inline detail step (categorical reason
10660
+ chips + a free-text comment) that opens as a disclosure directly below the thumbs. Emits; never
10661
+ persists — a host reflects a previously-recorded rating back via `value` (+ `disabled` for a
10662
+ read-only display). Activating the pressed thumb again toggles it off to `null` unless its own detail
10663
+ panel is currently open, in which case that click re-opens the panel instead.
10664
+
10665
+ **Properties:** `value: 'up' | 'down' | null = null` (reflected), `reasons: MessageFeedbackReason[] =
10666
+ []` (attribute: false, each `{ id, label }`), `commentable: boolean = false` (reflected) adds a
10667
+ free-text comment field, `detailFor: 'down' | 'both' = 'down'` (attribute `detail-for`) — which
10668
+ rating opens the detail panel, and `disabled: boolean = false` (reflected) for a read-only display.
10669
+
10670
+ **Methods:** `focus()` focuses the thumb matching the current `value` (the up thumb when `null`);
10671
+ `blur()` blurs both thumbs.
10672
+
10673
+ **Events:** `lyra-change` — `detail: { value }`, fired when a thumb's rating changes or clears.
10674
+ `lyra-submit` — `detail: { value, reasonIds, comment }`, fired by the panel's submit button.
10675
+
10676
+ **CSS parts:** `base` (the root), `thumbs` (wrapper around both thumb buttons), `up-button`,
10677
+ `down-button`, `panel` (the inline detail disclosure, only rendered when `reasons` is non-empty or
10678
+ `commentable` is set), `reasons` (the reason-chip group), `comment` (the comment `<textarea>`), and
10679
+ `submit-button`.
10680
+
10681
+ ## `lyra-page-rail`
10682
+
10683
+ A virtualized vertical thumbnail rail for page-addressed documents, with per-page highlight heat
10684
+ markers. Two modes: **wired** (`viewer`/`for` supply a live page source, e.g. `<lyra-pdf-viewer>` —
10685
+ thumbnails render lazily as rows materialize, and the rail tracks page/count from the viewer's own
10686
+ events) and **mediated** (`page-count`/`page` are host-bound directly, rows render a placeholder
10687
+ glyph — still a fully functional pager). In wired mode the viewer's `page` is the single source of
10688
+ truth.
10689
+
10690
+ **Properties:** `viewer: PageThumbnailSource | null = null` (attribute: false) — the wired viewer.
10691
+ `for: string = ''` — an id selector alternative to setting `viewer` directly. `pageCount: number = 0`
10692
+ (attribute `page-count`) and `page: number = 1` (reflected) — mediated-mode page state.
10693
+ `highlights: LyraHighlight[] = []` (attribute: false) — drives the per-page heat markers.
10694
+ `thumbWidth: number = 96` (attribute `thumb-width`) and `label: string = ''`.
10695
+
10696
+ **Events:** `lyra-page-select` — a page row was activated (click, or Enter/Space on a focused row).
10697
+ `detail: { page }`. In wired mode the rail also sets `viewer.page` itself.
10698
+
10699
+ **CSS parts:** `base` (the rail), `pages` (the embedded `<lyra-virtual-list>`), `page` (one page
10700
+ button), `thumbnail` (the thumbnail canvas wrapper), `page-number` (the visible page number), `heat`
10701
+ (the heat-marker cluster), and `heat-dot` (one tone-colored heat marker, or the `+n` overflow
10702
+ marker).
10703
+
10704
+ **Themeable custom properties:** `--lyra-page-rail-height` (default `var(--lyra-size-24rem)`) — block
10705
+ size of the virtualized rail.
10706
+
10707
+ ## `lyra-push-to-talk`
10708
+
10709
+ A mic capture button owning the full `getUserMedia` + `MediaRecorder` lifecycle: permission request,
10710
+ recording, optional chunked streaming, teardown. The one place in this library that touches the
10711
+ microphone — no SDK, no LiveKit/ElevenLabs import, native browser APIs only. `mode="hold"` (the
10712
+ default) is a press-and-hold gesture; `mode="toggle"` is click-to-start/click-to-stop with
10713
+ `aria-pressed`. Escape cancels the in-progress take in either mode.
10714
+
10715
+ **Properties:** `mode: 'hold' | 'toggle' = 'hold'` (reflected), `timesliceMs: number = 0` (attribute
10716
+ `timeslice-ms`), `mimeType: string = ''` (attribute `mime-type`), `deviceId: string = ''` (attribute
10717
+ `device-id`), `audioConstraints?: MediaTrackConstraints` (attribute: false), `levelEvents: boolean =
10718
+ false` (attribute `level-events`), `maxDurationMs: number = 0` (attribute `max-duration-ms`),
10719
+ `showTimer: boolean = true` (attribute `show-timer`), `disabled: boolean = false` (reflected), and
10720
+ readonly `state: 'idle' | 'requesting' | 'denied' | 'recording' | 'error' = 'idle'` (reflected to
10721
+ `data-state`), and readonly `stream: MediaStream | null`.
10722
+
10723
+ **Methods:** `start()`, `stop()`, and `cancel()` drive the capture lifecycle imperatively (mirroring
10724
+ the pointer/keyboard gestures).
10725
+
10726
+ **Slots:** `icon` (replaces the default mic glyph) and `recording-icon` (replaces the default
10727
+ recording-state pulse glyph).
10728
+
10729
+ **Events:** `lyra-record-start` (`detail: { stream }`), `lyra-record-chunk` (`detail: { blob }`, only
10730
+ when `timeslice-ms > 0`), `lyra-record-stop` (`detail: { blob, durationMs }`), `lyra-record-cancel`
10731
+ (no detail), `lyra-record-error` (`detail: { error }`), `lyra-level` (`detail: { level }`, opt-in via
10732
+ `level-events`), and `lyra-state-change` (`detail: { state }`).
10733
+
10734
+ **CSS parts:** `trigger` (the capture button), `icon`, `pulse` (rendered only while recording),
10735
+ `timer` (the `M:SS` elapsed-time readout, only while recording and `show-timer`), and `status`
10736
+ (visible status text for the `requesting`/`denied`/`error`/unsupported states).
10737
+
10738
+ ## `lyra-rubric-form`
10739
+
10740
+ A configurable annotation rubric (LangSmith annotation-queue style): score, category, and
10741
+ freeform-comment keys with a submit-and-next flow for working through an eval queue. Each
10742
+ `RubricKey.type` routes to an existing sibling control: `score` renders `<lyra-segmented>` or
10743
+ `<lyra-slider>`; `category` renders `<lyra-select>` or `<lyra-checkbox-group>` (`multiple`); `comment`
10744
+ renders `<lyra-textarea>`.
10745
+
10746
+ **Properties:** `keys: RubricKey[] = []` (attribute: false, each `{ key, type, label?, description?,
10747
+ required?, min?, max?, step? }`), `value: RubricValue = {}` (attribute: false), `itemId: string = ''`
10748
+ (attribute `item-id`, reflected), `hasNext: boolean = false` (attribute `has-next`), `skippable:
10749
+ boolean = false`, and the shared form properties `name` and `disabled`. `errors: Record<string,
10750
+ string>` is the current per-key validation-message state.
10751
+
10752
+ **Slots:** `actions` — extra host controls rendered in the footer beside Submit/Skip.
10753
+
10754
+ **Events:** `lyra-input` (`detail: { value }`), `lyra-validity-change` (`detail: { valid, errors }`,
10755
+ fired only on an actual change), `lyra-submit` (`detail: { value, itemId }`), and `lyra-skip`
10756
+ (`detail: { itemId }`, `skippable` only).
10757
+
10758
+ **CSS parts:** `base` (the outer wrapper), `field` (one key's wrapper), `label`, `description`,
10759
+ `scale` (the rendered score/category/comment control's wrapper), `error` (a field-level validation
10760
+ message), `footer`, `submit`, `skip` (only rendered when `skippable`), `empty` (shown when `keys` has
10761
+ no entries), and `unsupported` (the fallback note for a key whose `type` is outside the three
10762
+ supported ones).
10763
+
10764
+ ## `lyra-span-waterfall`
10765
+
10766
+ The horizontal-timeline projection of the same `LyraSpan[]` `<lyra-trace-tree>` consumes: a time
10767
+ axis, one row per span in start order, status-toned bars (Langfuse timeline / Temporal
10768
+ event-history style).
10769
+
10770
+ **Properties:** `spans: LyraSpan[] = []` (attribute: false), `activeSpanId: string | null = null`
10771
+ (attribute `active-span-id`), `viewStartMs: number | null = null` (attribute `view-start-ms`) and
10772
+ `viewEndMs: number | null = null` (attribute `view-end-ms`) — override the auto-computed time
10773
+ window, `hideAxis: boolean = false` (attribute `hide-axis`), and `label: string = ''`.
10774
+
10775
+ **Events:** `lyra-span-select` — `detail: { id }`, a bar/row was activated (click, Enter, Space).
10776
+
10777
+ **CSS parts:** `base`, `axis` (the time-ruler row, hidden when `hideAxis`), `tick`, `tick-label`,
10778
+ `row`, `name` (the row's name gutter), `bar-track`, `bar` (the interactive, focusable status-toned
10779
+ bar), `meta` (secondary row info, shown inline under 480px), `status-text`, `duration`, `empty` (shown
10780
+ when `spans` is empty), and `live-region`.
10781
+
10782
+ **Themeable custom properties:** `--lyra-span-waterfall-name-width` (default `8rem`) and
10783
+ `--lyra-span-waterfall-stripe-speed` (a `running` span's striped-bar animation duration; defaults to
10784
+ `--lyra-transition-ambient`).
10785
+
10786
+ ## `lyra-task-list`
10787
+
10788
+ A live, collapsible tracker for an agent's plan: ordered steps with per-step lifecycle status and one
10789
+ level of nested sub-steps, embedded in the transcript. `items` is controlled and never mutated by this
10790
+ component. Unlike `<lyra-stepper>`'s single-`current` navigation, task-list is a read-only status
10791
+ report: several steps may be `running` at once, there is no selection, and status changes are
10792
+ announced through an internal `<lyra-live-region>`.
10793
+
10794
+ **Properties:** `items: TaskItem[] = []` (attribute: false, each `{ id, label, status, detail?,
10795
+ children? }` where `status` is `'pending' | 'running' | 'success' | 'error'`), `label: string =
10796
+ 'Tasks'`, `expanded: boolean = true` (reflected), and `collapsible: boolean = true`.
10797
+
10798
+ **Slots:** `detail-<id>` — dynamic, one per item id (e.g. `slot="detail-step-3"`); rich detail under
10799
+ that item's label, typically a `<lyra-tool-call-chip>` or file `<lyra-chip>`.
10800
+
10801
+ **Events:** `lyra-toggle` — the header was activated, expanding or collapsing the panel. `detail: {
10802
+ expanded }`.
10803
+
10804
+ **CSS parts:** `base`, `header` (a `<button>` when `collapsible`, a plain heading otherwise), `label`,
10805
+ `summary` (the visible "N of M completed" summary, top-level items only), `toggle` (the chevron
10806
+ indicator, only rendered when `collapsible`), `body` (the list of items, `hidden` while collapsed),
10807
+ `item` (`role="listitem"`; carries `data-status`/`data-id`/`data-depth`), `status-icon`, `item-label`,
10808
+ `item-detail`, and `item-children` (the nested `role="list"` wrapper around a top-level item's
10809
+ children).
10810
+
10811
+ **Themeable custom properties:** `--lyra-task-list-spin` (default `1s linear`) — running-status icon
10812
+ spin animation duration/timing.
10813
+
10814
+ ## `lyra-terminal`
10815
+
10816
+ A read-only ANSI console for streamed agent/tool output. Not a PTY: no stdin/keystroke handling, no
10817
+ cursor-addressed full-screen apps.
10818
+
10819
+ **Properties:** `content: string = ''` — initial/replaceable buffer content, parsed for ANSI/SGR
10820
+ codes. `maxScrollback: number = 5000` (attribute `max-scrollback`), `follow: boolean = true`
10821
+ (reflected) — stick-to-bottom, `wrap: boolean = true` (reflected), `copyable: boolean = true`
10822
+ (reflected) and `downloadable: boolean = false` (reflected) toggle the toolbar buttons, `filename:
10823
+ string = 'terminal.log'`, `announceOutput: boolean = false` (attribute `announce-output`),
10824
+ `accessibleLabel: string = ''` (attribute `aria-label`), `highlights: LyraHighlight[] = []` (attribute:
10825
+ false), and `activeHighlightId: string | null = null` (attribute: false). `anchorKinds` is a readonly
10826
+ `['page', 'text-quote', 'region']` for the shared anchor-target contract.
10827
+
10828
+ **Methods:** `write(text)` appends ANSI-parsed text to the buffer. `clear()` empties the buffer.
10829
+ `scrollToBottom()` and `scrollToAnchor(anchor)` control scroll position. `search(query)`,
10830
+ `searchNext()`, `searchPrevious()`, and `clearSearch()` drive in-buffer text search. `getPlainText()`
10831
+ returns the SGR-stripped plain text of the whole buffer.
10832
+
10833
+ **Events:** `lyra-copy` (`detail: { text }`), `lyra-download` (`detail: { filename }`),
10834
+ `lyra-follow-change` (`detail: { following }`), `lyra-search-change` (`detail: { query, matchCount,
10835
+ activeIndex }`), `lyra-highlight-activate` (`detail: { id }`), and `lyra-text-select` (`detail: {
10836
+ text, anchor, rects }`).
10837
+
10838
+ **CSS parts:** `base`, `toolbar` (only rendered when copy/download are enabled), `copy-button`,
10839
+ `download-button`, `viewport` (the `role="log"` scrollable region), `line` (one rendered line; carries
10840
+ `data-line-number`/`data-match`/`data-highlight-tone`), `jump-to-latest` (shown while `follow` is
10841
+ disengaged and new output has arrived), and `announcer` (the visually-hidden `role="status"` region
10842
+ used when `announce-output` is set).
10843
+
10844
+ ## `lyra-trace-tree`
10845
+
10846
+ A collapsible span hierarchy for one agent/LLM trace (Langfuse/LangSmith run-tree style): kind icon,
10847
+ name, status, an inline duration bar on the shared trace time scale, and optional tokens/cost
10848
+ columns. Consumes the same `LyraSpan[]` as `<lyra-span-waterfall>`.
10849
+
10850
+ **Properties:** `spans: LyraSpan[] = []` (attribute: false), `activeSpanId: string | null = null`
10851
+ (attribute `active-span-id`), `label: string = ''`, `showTokens: boolean = false` (attribute
10852
+ `show-tokens`), `showCost: boolean = false` (attribute `show-cost`), and `hideBars: boolean = false`
10853
+ (attribute `hide-bars`).
10854
+
10855
+ **Methods:** `expandAll()` and `collapseAll()` set every row's expanded state at once.
10856
+
10857
+ **Events:** `lyra-span-select` (`detail: { id }`, a row was activated) and `lyra-span-toggle`
10858
+ (`detail: { id, expanded }`, a row was expanded or collapsed).
10859
+
10860
+ **CSS parts:** `base` (`role="tree"`), `header` (the column-header row, only when
10861
+ `showTokens`/`showCost`), `row` (`role="treeitem"`), `toggle`, `icon`, `name`, `detail`, `status-text`,
10862
+ `duration`, `tokens-in`, `tokens-out` (when `showTokens`), `cost` (when `showCost`), `bar-track`,
10863
+ `bar`, `empty` (shown when `spans` is empty), and `live-region`.
10864
+
10865
+ ## `lyra-file-tree`
10866
+
10867
+ A file-explorer preset over `<lyra-tree>` + `<lyra-file-icon>`: path-keyed nodes with
10868
+ git-status/diff-count badges, lazy directory loading, and select/open events.
10869
+
10870
+ **Properties:** `nodes: FileTreeNode[] = []` (attribute: false), `selectedPath: string | null = null`
10871
+ (attribute `selected-path`), and `label: string = ''`.
10872
+
10873
+ **Methods:** `setChildren(path, children)` supplies a lazily-loaded directory's children.
10874
+ `revealPath(path)` expands every ancestor directory and scrolls the target row into view, resolving
10875
+ `true` once found. `expandAll()` and `collapseAll()` forward to the underlying `<lyra-tree>`.
10876
+
10877
+ **Events:** `lyra-file-select` (`detail: { path, node }`, a row was activated), `lyra-file-open`
10878
+ (`detail: { path, node }`, Enter/click on an already-selected file row), and `lyra-load-children`
10879
+ (`detail: { path }`, a lazy unloaded directory expanded).
10880
+
10881
+ **CSS parts:** `base` — the root wrapper.
10882
+
10883
+ ## `lyra-activity-feed`
10884
+
10885
+ An append-only streaming log of granular agent actions ("Searching the web…", "Read
10886
+ src/index.ts"), collapsing to a localized "Completed N steps" summary once the run is over. Entries
10887
+ never change state once added — a step whose status mutates in place belongs to `<lyra-task-list>`
10888
+ instead. Implements the shared follow (stick-to-bottom) contract. At/above `virtualizeThreshold`
10889
+ entries, the body renders through an internal `<lyra-virtual-list>` instead of a plain keyed list.
10890
+
10891
+ **Properties:** `entries: ActivityEntry[] = []` (attribute: false), `mode: 'live' | 'post-hoc' =
10892
+ 'live'` (reflected), `follow: boolean = true` (reflected), `expanded: boolean = false` (reflected),
10893
+ `label: string = 'Activity'`, `showTimestamps: boolean = false` (attribute `show-timestamps`),
10894
+ `formatTimestamp?: (date: Date) => string` (attribute: false), `renderText?: (entry: ActivityEntry)
10895
+ => TemplateResult` (attribute: false) — overrides the default plain-text `entry-text` rendering with
10896
+ arbitrary rich content (e.g. rendered markdown, or markdown plus a trailing tool-call chip list),
10897
+ identically whether or not the feed is currently virtualized; fully replaces `[part="entry-text"]`
10898
+ rather than augmenting it, and `virtualizeThreshold: number = 200` (attribute
10899
+ `virtualize-threshold`).
10900
+
10901
+ **Events:** `lyra-toggle` (`detail: { expanded }`, the header was activated) and
10902
+ `lyra-follow-change` (`detail: { following }`, `follow` released or re-engaged).
10903
+
10904
+ **CSS parts:** `base`, `header` (a `<button>`), `status-dot` (pulses while `mode="live"`),
10905
+ `summary`, `toggle`, `body` (the scrollable region, or the internal virtual-list), `entry` (carries
10906
+ `data-tone`), `entry-icon`, `entry-text`, and `entry-timestamp` (only while `showTimestamps` and a
10907
+ valid `timestamp` is set).
10908
+
10909
+ **Themeable custom properties:** `--lyra-activity-feed-max-height` (default `16rem`) — cap on how
10910
+ tall the expanded body grows before it scrolls internally.
10911
+
10912
+ ## `lyra-commit-card`
10913
+
10914
+ A compact commit summary (subject, author/time, diffstat, per-file changes) that links file rows out
10915
+ to a diff view.
10916
+
10917
+ **Properties:** `hash: string = ''`, `message: string = ''`, `author: string = ''`, `timestamp?:
10918
+ number` (attribute: false), `files: CommitFileChange[] = []` (attribute: false), `filesCollapsed:
10919
+ boolean = true` (attribute `files-collapsed`, reflected), and `copyable: boolean = true` (reflected).
10920
+
10921
+ **Slots:** `actions` — trailing header controls (e.g. an "open PR" button).
10922
+
10923
+ **Events:** `lyra-file-select` (`detail: { path }`), `lyra-toggle` (`detail: { collapsed }`), and
10924
+ `lyra-copy` (`detail: { text }`, the full hash was copied).
10925
+
10926
+ **CSS parts:** `base`, `subject`, `body`, `hash`, `meta`, `author`, `time`, `diffstat`, `additions`,
10927
+ `deletions`, `files-toggle`, `file` (carries `data-status`), `file-path`, `file-additions`,
10928
+ `file-deletions`, `copy-button`, and `actions`.
10929
+
10930
+ ## `lyra-image-viewer`
10931
+
10932
+ A full pan/zoom raster-image viewer with labeled region highlights and opt-in region annotation, the
10933
+ landing surface for `region`-anchored citations. Distinct from `<lyra-svg-viewer>` (rendered SVG
10934
+ documents) and `<lyra-image-comparer>` (before/after slotted surfaces). Adopts `DocumentAnchorTarget`
10935
+ with `anchorKinds: ['region']` only — no text selection is bound.
10936
+
10937
+ **Properties:** `src: string = ''`, `name: string = ''`, `alt?: string`, `fit: 'contain' | 'width' |
10938
+ 'actual' = 'contain'` (reflected), `zoom: number = 1` (reflected), `rotation: 0 | 90 | 180 | 270 = 0`
10939
+ (reflected), and `annotatable: boolean = false` (reflected).
10940
+
10941
+ **Methods:** `rotate()` advances `rotation` by 90°. `zoomIn()`, `zoomOut()`, and `resetZoom()` adjust
10942
+ the embedded zoomable-frame's zoom.
10943
+
10944
+ **Events:** `lyra-load` (`detail: { naturalWidth, naturalHeight }`), `lyra-zoom-change` (`detail: {
10945
+ zoom }`), `lyra-rotation-change` (`detail: { rotation }`), `lyra-fit-change` (`detail: { fit }`),
10946
+ `lyra-highlight-activate` (`detail: { id }`), `lyra-annotation-create` (`detail: { anchor }`, kind
10947
+ `'region'`), `lyra-anchor-result` (`detail: { found }`), and `lyra-render-error` (`detail: { error
10948
+ }`).
10949
+
10950
+ **CSS parts:** `base`, `toolbar`, `fit-control`, `rotate-button`, `annotate-toggle`, `frame` (the
10951
+ embedded `lyra-zoomable-frame`), `image-wrapper`, `image`, `highlight-layer`, `highlight` (carries
10952
+ `data-tone`/`data-active`), `highlight-label`, `annotation-box`, and `error`.
10953
+
10954
+ ## `lyra-transcript-feed`
10955
+
10956
+ Live captions for an in-progress voice session: speaker-grouped entries, interim-vs-final styling
10957
+ with in-place upgrades keyed by `id`, and a stick-to-bottom auto-scroll with release, the same
10958
+ `follow`/`lyra-follow-change` contract `<lyra-terminal>` uses. Live captions only — recorded-media
10959
+ transcript sync is a separate concern.
10960
+
10961
+ **Properties:** `entries: LyraTranscriptEntry[] = []` (attribute: false), `follow: boolean = true`
10962
+ (reflected), `showTimestamps: boolean = false` (attribute `show-timestamps`), `formatTimestamp?:
10963
+ (epochMs: number) => string` (attribute: false), `maxRenderedEntries: number = 0` (attribute
10964
+ `max-rendered-entries`), `label: string = ''` — accessible name for the `role="log"` region
10965
+ (default: the localized `transcriptFeedLabel`), and `accessibleLabel: string | null = null`
10966
+ (attribute `aria-label`) — overrides the log's computed accessible name, winning over `label` and
10967
+ the localized default; attribute-reflects from a host-level `aria-label`.
10968
+
10969
+ **Methods:** `scrollToBottom()` re-engages `follow` and scrolls to the latest entry.
10970
+
10971
+ **Slots:** `empty` — custom empty state (default: the localized "No transcript yet").
10972
+
10973
+ **Events:** `lyra-follow-change` — `detail: { following }`, fires on every `follow` transition.
10974
+
10975
+ **CSS parts:** `base` (the scroll container), `log` (the `role="log"` region wrapping final entries
10976
+ only), `entry`, `speaker` (omitted for a row repeating the previous row's speaker), `text`
10977
+ (`dir="auto"`), `timestamp` (only while `show-timestamps`), `interim` (present alongside `entry` on
10978
+ an interim row), `jump-button` (shown only while `follow` is `false`), and `empty`.
10979
+
10980
+ ## `lyra-av-player`
10981
+
10982
+ An audio/video player built on a native `<audio>`/`<video>` element, plus a cue transcript synced to
10983
+ `currentTime`, `time-range` anchor/highlight support, an optional dependency-free waveform (peaks
10984
+ in, no in-component decoding), and playback-rate control. Owns recorded-media transcript sync —
10985
+ distinct from `<lyra-transcript-feed>` (live captions for an in-progress voice session) and
10986
+ `<lyra-playback>` (an index stepper, no media). Adopts `DocumentAnchorTarget` with
10987
+ `anchorKinds: ['time-range']` only — no text selection is bound. The transcript virtualizes through
10988
+ `<lyra-virtual-list>` the same way `lyra-pdf-viewer` virtualizes pages.
10989
+
10990
+ **Properties:** `src: string = ''`, `name: string = ''`, `kind?: 'audio' | 'video'` (attribute:
10991
+ false auto-detection override), `mimeType: string = ''` (attribute `mime-type`), `poster: string =
10992
+ ''`, `loop: boolean = false`, `muted: boolean = false`, `preload: 'none' | 'metadata' | 'auto' =
10993
+ 'metadata'`, `playbackRate: number = 1` (attribute `playback-rate`, reflected), `rates: number[] =
10994
+ [0.75, 1, 1.25, 1.5, 2]` (attribute: false), `cues: LyraAvCue[] = []` (attribute: false), `peaks:
10995
+ number[] = []` (attribute: false), and `tracks: LyraAvTrack[] = []` (attribute: false).
10996
+ `LyraAvCue = { id, start, end?, text, speaker? }`; `LyraAvTrack = { src, kind: 'subtitles' |
10997
+ 'captions' | 'descriptions', srclang, label, default? }`.
10998
+
10999
+ **Methods:** `play()`, `pause()`, and `toggle()` proxy the native media element. `seek(seconds)`
11000
+ sets `currentTime` and forces an immediate `lyra-time-change`. `search(query)` resolves the match
11001
+ count; `searchNext()`/`searchPrevious()` wrap; `clearSearch()` resets.
11002
+
11003
+ **Events:** `lyra-play`, `lyra-pause`, `lyra-load` (`detail: { duration, kind }`), `lyra-time-change`
11004
+ (`detail: { currentTime }`, throttled to at most 4/s while playing plus one extra per `seek()`),
11005
+ `lyra-rate-change` (`detail: { rate }`), `lyra-cue-change` (`detail: { id }`, `id` is `null` when no
11006
+ cue is active), `lyra-highlight-activate` (`detail: { id }`), `lyra-anchor-result` (`detail: {
11007
+ found }`), `lyra-search-change` (`detail: { query, matchCount, activeIndex }`), and
11008
+ `lyra-render-error` (`detail: { error }`).
11009
+
11010
+ **CSS parts:** `base`, `media` (the native `<audio>`/`<video>` element), `toolbar`, `rate-select`,
11011
+ `timeline` (click-to-seek and arrow-key seeking), `timeline-marker` (one per `time-range` highlight;
11012
+ `data-tone`, `data-active`), `transcript` (the `<lyra-virtual-list>` itself), `cue` (`aria-current`,
11013
+ `data-match`, `data-active-match`), `cue-time`, `cue-speaker`, `cue-text`, and `error`.
11014
+
11015
+ ## `lyra-test-results`
11016
+
11017
+ A pass/fail suite summary with per-status counts, status filter toggles, and per-test rows whose
11018
+ failures auto-expand by default and can host rich slotted detail (e.g. a diff or code block)
11019
+ alongside the plain failure message.
11020
+
11021
+ **Properties:** `suites: TestSuiteResult[] = []` (attribute: false), `statusFilter: TestStatus[] =
11022
+ []` (attribute: false), and `autoExpandFailures: boolean = true` (attribute
11023
+ `auto-expand-failures`).
11024
+
11025
+ **Slots:** `detail-{testId}` — rich failure detail for that test, rendered after its plain message
11026
+ text once the row is expanded.
11027
+
11028
+ **Events:** `lyra-test-select` (`detail: { suiteId, testId }`, a test row's name was activated),
11029
+ `lyra-filter-change` (`detail: { statuses }`, the status-set filter changed), and `lyra-toggle`
11030
+ (`detail: { id, expanded }`, a row's failure detail was expanded/collapsed).
11031
+
11032
+ **CSS parts:** `base`, `summary` (the status-count strip), `count` (carries `data-status`), `filter`,
11033
+ `filter-toggle` (carries `data-status`/`aria-pressed`), `suite`, `suite-header`, `test` (carries
11034
+ `data-status`), `test-status`, `test-name`, `test-duration`, `test-expand-toggle`, `failure`
11035
+ (hidden while collapsed), and `failure-message`.
11036
+
11037
+ ## `lyra-env-list`
11038
+
11039
+ A masked key/value list for environment variables and secrets, with per-row reveal and copy.
11040
+ Masking is presentational, not a security boundary: the real value sits in a DOM property
11041
+ regardless of mask state.
11042
+
11043
+ **Properties:** `entries: EnvEntry[] = []` (attribute: false), `revealable: boolean = true`
11044
+ (reflected), `copyable: boolean = true` (reflected), and `label: string = ''`.
11045
+
11046
+ **Events:** `lyra-reveal-change` (`detail: { name, revealed }`) and `lyra-copy` (`detail: { text }`,
11047
+ the real unmasked value).
11048
+
11049
+ **CSS parts:** `base` (the `<dl>` root), `name` (the `<dt>` text), `value-cell` (the `<dd>` wrapping
11050
+ an entry's value text and buttons), `value` (carries `data-masked`), `reveal-button`, and
11051
+ `copy-button`.
11052
+
11053
+ ## `lyra-handoff-divider`
11054
+
11055
+ A labeled semantic separator marking control transfer between agents in a transcript ("Transferred
11056
+ to Research Agent"), with an optional agent avatar. Purely presentational: no events, no
11057
+ interactivity, no restore semantics. The computed label is announced once, on first connect,
11058
+ through an internal `<lyra-live-region>`.
11059
+
11060
+ **Properties:** `agent: string = ''`, `fromAgent: string = ''` (attribute `from-agent`), and `label:
11061
+ string = ''`.
11062
+
11063
+ **Slots:** `avatar` — the incoming agent's `<lyra-avatar>` (or icon), hidden entirely while empty.
11064
+
11065
+ **CSS parts:** `base` (the separator root, `role="separator"`), `line` (each of the two flanking
11066
+ rules), `chip` (the visual `aria-hidden` chip wrapping the avatar and label), `avatar` (wrapper
11067
+ around the `avatar` slot, only shown while the slot has content), and `label`.
11068
+
11069
+ ## `lyra-chat-viewport`
11070
+
11071
+ The transcript scroll container: owns stick-to-bottom behavior while an answer streams, the "jump to
11072
+ latest" pill, and the unread divider. Two supported content shapes, auto-detected: ordinary element
11073
+ children (typically `lyra-chat-message`s — *slotted mode*), or exactly one `lyra-virtual-list`
11074
+ (*virtual mode*, detected via `instanceof`). In virtual mode this component defers all scrolling to
11075
+ the slotted list's own `scrollToIndex()`. Follow/release state machine: while `follow` is engaged,
11076
+ content growth re-scrolls to the end; release happens only on a user-intent gesture (wheel,
11077
+ touchmove, scrollbar-drag, or PageUp/ArrowUp/Home while the log region has focus) that leaves the
11078
+ view more than `bottomThreshold` from the end — a scroll caused by this component's own programmatic
11079
+ scrolling, or by a layout shift, never releases it. Reaching the bottom again by any means re-engages
11080
+ `follow`.
11081
+
11082
+ **Properties:** `follow: boolean = true` (reflected) — component-managed stick-to-bottom state,
11083
+ host-writable: setting `true` scrolls to the end and re-engages following, setting `false` releases
11084
+ it. `bottomThreshold: number = 24` (attribute `bottom-threshold`) — px distance from the end still
11085
+ counted as "at bottom." `unreadStartIndex: number | null = null` (attribute `unread-start-index`) —
11086
+ index of the first unread item (element-child index in slotted mode, `items` index in virtual mode);
11087
+ `null` disables both the divider and the pill's unread count. `label: string = ''` — accessible name
11088
+ for the log region, defaults to the localized `chatViewportLabel`. `accessibleLabel: string | null =
11089
+ null` (attribute `aria-label`) — host `aria-label`, forwarded to the internal `role="log"` element
11090
+ (an `aria-label` left on the host itself names nothing, since the log role lives inside the shadow
11091
+ root); wins over `label` and the localized default.
11092
+
11093
+ **Methods:** `scrollToBottom(options?)` — scrolls to the end and re-engages `follow`; default
11094
+ `smooth`, forced to `auto` under `prefers-reduced-motion`. `scrollToUnread(options?)` — scrolls the
11095
+ unread divider to the top of the view, resolving `false` when `unreadStartIndex` is `null`/out of
11096
+ range; does not re-engage `follow`.
11097
+
11098
+ **Events:** `lyra-follow-change` — `detail: { following }`, fired whenever `follow` flips (user
11099
+ scroll-up release, or reaching the bottom again). Never fired for the initial mount state.
11100
+
11101
+ **Slots:** default — the transcript: ordinary element children, or exactly one `lyra-virtual-list`.
11102
+
11103
+ **CSS parts:** `base` (the positioning root), `scroll` (the scroll container, `role="log"`,
11104
+ `tabindex="0"`; in virtual mode it stops scrolling itself but keeps the role), `content` (the
11105
+ slotted-content wrapper the growth observers watch), `jump-pill` (the built-in jump-to-latest button,
11106
+ absent while `follow` is engaged), `unread-divider` (the "New messages" separator, slotted mode
11107
+ only).
11108
+
11109
+ Renders no messages and computes no unread state itself — the host supplies `unreadStartIndex`; no
11110
+ virtualization of its own (`lyra-virtual-list`); not a generic overflow surface (`lyra-scroller`); no
11111
+ message semantics (`lyra-chat-message`).
11112
+
11113
+ ```html
11114
+ <lyra-chat-viewport unread-start-index="12" @lyra-follow-change=${(e) => console.log(e.detail.following)}>
11115
+ <lyra-chat-message role="user">…</lyra-chat-message>
11116
+ <lyra-chat-message role="assistant" status="streaming">
11117
+ <lyra-streaming-text streaming .content=${partial}></lyra-streaming-text>
11118
+ </lyra-chat-message>
11119
+ </lyra-chat-viewport>
11120
+ <lyra-chat-composer status="streaming"></lyra-chat-composer>
11121
+ ```
11122
+
11123
+ ## `lyra-suggestion-chips`
11124
+
11125
+ Starter prompts (empty thread) and follow-up suggestions (after a response) as a horizontally
11126
+ scrollable chip row; activation hands the prompt to the host, which decides whether to compose it
11127
+ into an input or send it directly. Never writes into a composer or sends anything itself.
11128
+ Streaming-friendly: chips render through a keyed `repeat()` on `id`, so replacing follow-ups
11129
+ mid-conversation preserves focus on any chip whose `id` survives.
11130
+
11131
+ **Properties:** `suggestions: ChatSuggestion[] = []` (attribute: false, each `{ id, label, detail? }`
11132
+ — `detail` is an optional secondary line). Empty renders nothing at all. `wrap: boolean = false`
11133
+ (reflected) — wraps into multiple rows instead of a single horizontally scrollable line. `label:
11134
+ string = ''` — accessible name for the group, defaults to the localized `suggestionsLabel`.
11135
+
11136
+ **Events:** `lyra-suggestion-select` — `detail: { id, label }`.
11137
+
11138
+ **CSS parts:** `base` (the labeled group), `chip` (each suggestion button), `chip-label` (the primary
11139
+ text), `chip-detail` (the secondary line, only rendered when `detail` is set).
11140
+
11141
+ Keyboard: roving tabindex across chips; ArrowLeft/ArrowRight (direction-aware) plus Home/End;
11142
+ Enter/Space activate. Renders inside an internal `lyra-scroller` (`orientation="horizontal"`,
11143
+ `hide-scrollbar`) unless `wrap` is set.
11144
+
11145
+ ```html
11146
+ <lyra-suggestion-chips .suggestions=${followUps}
11147
+ @lyra-suggestion-select=${(e) => (composer.value = e.detail.label)}></lyra-suggestion-chips>
11148
+ <lyra-chat-composer></lyra-chat-composer>
11149
+ ```
11150
+
11151
+ ## `lyra-thread-list`
11152
+
11153
+ The conversation sidebar: a grouped, searchable list of chat sessions with pin/archive/delete/rename
11154
+ affordances. *Data mode* (non-empty `threads`, or empty `threads` with nothing slotted) renders every
11155
+ row as a `lyra-conversation-item` inside an internal `lyra-virtual-list` — virtualized by
11156
+ construction, scroll position and per-row state survive a `threads` replacement; zero rows renders
11157
+ the built-in empty state. *Slotted mode* (empty `threads` *and* real slotted content) renders
11158
+ host-supplied `lyra-conversation-item`s from the default slot as-is: no grouping, virtualization, or
11159
+ row actions in that mode. No thread CRUD or persistence — every mutation
11160
+ (`lyra-thread-pin`/`-archive`/`-delete`/`-rename`) is a controlled event carrying the *requested* new
11161
+ state; the host mutates `threads`.
11162
+
11163
+ **Properties:** `threads: ChatThread[] = []` (attribute: false, each `{ id, title, excerpt?,
11164
+ timestamp?, pinned?, archived? }`). `activeId: string = ''` (attribute `active-id`) — data mode:
11165
+ marks the matching row `active`/`aria-current` and scrolls it into view. `searchable: boolean =
11166
+ false` (reflected) — shows the built-in search field. `filter?: (thread, query) => boolean`
11167
+ (attribute: false) — overrides the default case-insensitive `title` + `excerpt` substring match.
11168
+ `grouping: 'date' | 'none' = 'date'` — data mode: bucket rows under localized date headers
11169
+ (Pinned/Today/Yesterday/Previous 7 days/Previous 30 days/one bucket per month/Archived), or a flat
11170
+ list. `rowActions: ThreadRowAction[] = []` (attribute: false, each `'pin' | 'archive' | 'delete'`) —
11171
+ data mode only: built-in icon buttons rendered into each row's `actions` slot. `showArchived: boolean
11172
+ = false` (attribute `show-archived`, reflected) — data mode: include `archived` threads (in their own
11173
+ trailing group). `editable: boolean = true` (reflected) — forwarded to each data-mode row's inline
11174
+ rename. `label: string = ''` — accessible name for the list region, defaults to the localized
11175
+ `threadListLabel`. `wrapRow?: (thread: ChatThread, row: TemplateResult) => TemplateResult` (attribute:
11176
+ false) — data mode only: wraps each row's built-in `lyra-conversation-item` with host-supplied content
11177
+ that has no home in the item's own `title`/`excerpt`/`meta`/`actions` surface (e.g. a leading purpose
11178
+ icon — the item has no default slot to receive one); unset renders the built-in row unwrapped.
11179
+
11180
+ **Slots:** default — slotted mode only: host-supplied `lyra-conversation-item`s, rendered in order.
11181
+ `empty` — replaces the built-in empty state.
11182
+
11183
+ **Events:** (data mode; slotted mode only ever fires `lyra-filter-change`) `lyra-select` (`detail: {
11184
+ id }`), `lyra-thread-pin` (`detail: { id, pinned }` — the requested new state), `lyra-thread-archive`
11185
+ (`detail: { id, archived }`), `lyra-thread-delete` (`detail: { id }`, no built-in confirmation),
11186
+ `lyra-thread-rename` (`detail: { id, title }`, re-emitted from the row's `lyra-rename`),
11187
+ `lyra-filter-change` (`detail: { text, matchCount }`).
11188
+
11189
+ **CSS parts:** `base`, `search`/`search-input` (the search field wrapper and `<input
11190
+ type="search">`), `list` (the list region), `empty`, `row-action` (a built-in pin/archive/delete icon
11191
+ button), `pin-glyph` (the small pin indicator on a pinned row), `group-header`/`row` (exported from
11192
+ the internal `lyra-virtual-list`).
11193
+
11194
+ ```html
11195
+ <lyra-thread-list
11196
+ searchable
11197
+ .threads=${threads}
11198
+ active-id=${activeThreadId}
11199
+ .rowActions=${['pin', 'archive', 'delete']}
11200
+ @lyra-select=${(e) => openThread(e.detail.id)}
11201
+ ></lyra-thread-list>
11202
+ ```
11203
+
11204
+ Composed with `lyra-split` (or `lyra-app-rail` + `lyra-responsive-panel`): thread-list in the start
11205
+ pane driving `activeId`, `lyra-chat-viewport` + `lyra-chat-composer` in the main pane.
11206
+
11207
+ ## `lyra-confirm-bar`
11208
+
11209
+ An inline, non-modal approve/deny block for one proposed action — the in-flow sibling of
11210
+ `lyra-tool-approval-dialog` for confirmations that should sit in the transcript instead of hijacking
11211
+ focus. Same `lyra-approve`/`lyra-deny` event shapes as the dialog, and the same
11212
+ `toolApprovalHeading`/`toolApprovalArgsLabel`/`deny`/`approve` localization keys, so the two always
11213
+ translate in lockstep. Non-modal by contract: no focus trap, no scroll lock, no Escape/backdrop
11214
+ semantics, and it never steals focus when it appears in the transcript. DOM and tab order put Deny
11215
+ before Approve. On activation, focus moves synchronously to `[part="status"]` (an always-rendered,
11216
+ `tabindex="-1"` element) before the Deny/Approve buttons unmount.
11217
+
11218
+ **Properties:** `toolName: string = ''` (attribute `tool-name`) — drives the default heading through
11219
+ the existing `toolApprovalHeading`/`toolApprovalGenericTool` dialog keys. `heading: string = ''` —
11220
+ free-form heading override for non-tool proposals; wins over `toolName`. `args: unknown = undefined`
11221
+ (attribute: false) — shown read-only inside a collapsed `lyra-details` + `lyra-json-viewer` when
11222
+ defined. `decision: 'approved' | 'denied' | null = null` (reflected) — decided state, set by the
11223
+ component on activation and host-writable (an externally-resolved decision renders identically but
11224
+ emits nothing). `tone: 'neutral' | 'danger' = 'neutral'` (reflected).
11225
+
11226
+ **Slots:** default — supplementary body content between the heading and the actions (e.g. a
11227
+ `lyra-diff-view`). `footer` — extra content at the start of the action row.
11228
+
11229
+ **Events:** `lyra-approve` (`detail: { args }` — the `args` prop as-is, identical shape to
11230
+ `lyra-tool-approval-dialog`), `lyra-deny` (no detail, identical to the dialog).
11231
+
11232
+ **CSS parts:** `base` (`role="group"`), `heading`/`tool-name`, `body`, `args` (the
11233
+ details/json-viewer wrapper, only rendered when `args` is defined), `footer`, `deny-button`,
11234
+ `approve-button` (named identically to the dialog's parts), `status` (the decided-state text, always
11235
+ present in the DOM as a focus landing spot).
11236
+
11237
+ ```html
11238
+ <lyra-tool-call-chip status="pending"></lyra-tool-call-chip>
11239
+ <lyra-confirm-bar tool-name="run_shell" .args=${args}
11240
+ @lyra-approve=${(e) => run(e.detail.args)} @lyra-deny=${() => cancel()}
11241
+ ></lyra-confirm-bar>
11242
+ ```
11243
+
11244
+ ## `lyra-checkpoint`
11245
+
11246
+ An inline conversation restore point: a labeled marker between messages whose Restore affordance
11247
+ confirms inline, then hands the host a `lyra-restore` event. This component persists and restores
11248
+ nothing itself — host state in, events out. Not a handoff or plain rule
11249
+ (`lyra-handoff-divider`/`lyra-divider`); not branch navigation across regenerated variants
11250
+ (`lyra-branch-picker`); not recorded-run playback (`lyra-playback`).
11251
+
11252
+ **Properties:** `checkpointId: string = ''` (attribute `checkpoint-id`) — opaque id echoed in the
11253
+ `lyra-restore` event detail. `label: string = ''` — checkpoint name; the localized `checkpointLabel`
11254
+ fallback renders while empty. `timestamp?: Date | string` (attribute: false) — optional creation
11255
+ time, rendered as `<time datetime>`, default `hour:minute` in `effectiveLocale`; invalid strings are
11256
+ treated as unset. `formatTimestamp?: (date: Date) => string` (attribute: false) — overrides the
11257
+ default rendering. `restorable: boolean = true` — when `false`, renders a plain marker with no
11258
+ button. `confirmRestore: boolean = true` (attribute `confirm-restore`) — gates the event behind an
11259
+ inline confirm step; a string-aware converter parses `confirm-restore="false"` correctly from plain
11260
+ HTML. `restoring: boolean = false` (reflected) — host-set busy state: the Restore button becomes
11261
+ `aria-disabled="true"` with a spinner beside the localized "Restoring…" text.
11262
+
11263
+ **Slots:** default — optional supplemental content under the marker row (e.g. what changed since
11264
+ this point).
11265
+
11266
+ **Events:** `lyra-restore` — `detail: { checkpointId, label }`; fired on Restore activation, after
11267
+ the inline confirm when `confirmRestore` is on. Not cancelable.
11268
+
11269
+ **CSS parts:** `base` (`role="group"`), `line` (each of the two flanking rules), `icon` (bookmark
11270
+ glyph), `label`, `timestamp`, `restore-button` (only while `restorable`), `confirm-group`,
11271
+ `confirm-prompt`, `confirm-button`, `cancel-button`.
11272
+
11273
+ **Themeable custom properties:** `--lyra-checkpoint-spin-duration` (default `1s`) — duration of one
11274
+ restoring-spinner rotation; stopped under reduced motion.
11275
+
11276
+ ```html
11277
+ <lyra-checkpoint checkpoint-id="ck_18" label="Before refactor" .timestamp=${t}
11278
+ @lyra-restore=${(e) => restoreTo(e.detail.checkpointId)}></lyra-checkpoint>
11279
+ ```
11280
+
11281
+ ## `lyra-usage-badge`
11282
+
11283
+ Compact, static resource strip for one message or run — tokens in/out, cost, latency — with a
11284
+ hover/focus tooltip breakdown. Purely formatting: computes no counts, rates, or prices; every segment
11285
+ is independently optional, and with nothing set, nothing renders at all (not even a focusable shell).
11286
+ The tooltip reuses `lyra-tool-call-chip`'s hover/focus/Escape/`aria-describedby` contract wholesale.
11287
+ Not `lyra-context-meter` (occupancy of a fixed capacity); not `lyra-generation-status` (live, with a
11288
+ Stop button) — this is static after the fact.
11289
+
11290
+ **Properties:** `tokensIn?: number` (attribute `tokens-in`) — input tokens, normalized to a
11291
+ non-negative integer, locale-formatted; segment omitted while unset/non-finite. `tokensOut?: number`
11292
+ (attribute `tokens-out`) — same rules. `costText: string = ''` (attribute `cost-text`) —
11293
+ pre-formatted cost (e.g. `"$0.012"`), rendered verbatim. `latencyMs?: number` (attribute
11294
+ `latency-ms`) — formatted with the shared duration algorithm (`820 -> "820ms"`, `1500 -> "1.5s"`), or
11295
+ `formatLatency` when set. `formatLatency?: (ms: number) => string` — overrides the built-in duration
11296
+ algorithm (which has no minutes/hours tier) in both the visible strip and the tooltip row; mirrors
11297
+ `lyra-activity-feed`'s `formatTimestamp` convention. `compact: boolean = false` — token counts render
11298
+ via `Intl.NumberFormat` `notation: 'compact'`; the tooltip always shows full grouped figures.
11299
+
11300
+ **Slots:** default — extra rows appended below the built-in tooltip breakdown (e.g. cache-read
11301
+ tokens); the visible strip itself is prop-driven only.
11302
+
11303
+ **CSS parts:** `base` (a focusable non-button `role="group"`, only rendered while at least one
11304
+ segment or the default slot has content), `tokens-in`, `tokens-out`, `cost`, `latency`, `tooltip`.
11305
+
11306
+ ```html
11307
+ <lyra-chat-message role="assistant" status="sent">
11308
+ <lyra-usage-badge slot="badges" tokens-in="1204" tokens-out="386"
11309
+ cost-text="$0.012" latency-ms="2350"></lyra-usage-badge>
11310
+ <lyra-markdown .content=${answer}></lyra-markdown>
11311
+ </lyra-chat-message>
11312
+ ```
11313
+
11314
+ ## `lyra-browser-frame`
11315
+
11316
+ Presentational "agent computer" viewport: a screenshot/frame stream (or slotted live media), a
11317
+ read-only URL display, action-ping overlays, and take-over/stop affordances. No automation transport
11318
+ (no CDP/WebRTC/WebSocket) and no input relay — take-over is an event; the host swaps in its own
11319
+ interactive element (e.g. an iframe). No replay scrubber (compose `lyra-playback` driving `frame-src`
11320
+ from a screenshot array); no console/network drawers (compose `lyra-terminal`/`lyra-json-viewer`); no
11321
+ pan/zoom of the frame content (slot the image/video inside a `lyra-zoomable-frame` instead, though
11322
+ the pings overlay assumes the unzoomed content box in that composition).
11323
+
11324
+ **Properties:** `frameSrc: string = ''` (attribute `frame-src`) — image/MJPEG stream URL rendered as
11325
+ an `<img>` (safe-URL-gated via `safeMediaSrc`); ignored once the default slot has content. `url:
11326
+ string = ''` — address shown read-only in the toolbar (`dir="ltr"`, truncating, full value in
11327
+ `title`). `status: 'idle' | 'connecting' | 'streaming' | 'stalled' = 'idle'` (reflected). `controller:
11328
+ 'agent' | 'user' = 'agent'` (reflected) — who is driving; switches the take-over button's label.
11329
+ `pings: BrowserPing[] = []` (attribute: false, each `{ id, x, y, kind: 'click' | 'type' | 'scroll' |
11330
+ 'move' }` — `x`/`y` are percent (0–100) of the frame's `object-fit: contain` content box,
11331
+ letterboxing-aware). `controls: boolean = true` — render the built-in take-over/stop buttons.
11332
+
11333
+ **Slots:** default — host-owned live element (e.g. `<video>` or an interactive `<iframe>`), replacing
11334
+ the `frame-src` image. `actions` — extra toolbar controls.
11335
+
11336
+ **Events:** `lyra-take-over` — `detail: { controller }`, the *requested* controller (`'user'` when
11337
+ "Take over" is pressed, `'agent'` when "Hand back" is). `lyra-stop` — stop the agent's browser
11338
+ session, no detail.
11339
+
11340
+ **CSS parts:** `base` (`role="group"`), `toolbar`, `url`, `status` (`role="status"`),
11341
+ `controller-badge`, `actions`, `take-over-button`, `stop-button`, `viewport`, `frame` (the
11342
+ `frame-src` `<img>`, absent once the default slot is populated), `ping` (one action-ping marker,
11343
+ carries `data-kind`).
11344
+
11345
+ **Themeable custom properties:** `--lyra-browser-frame-aspect-ratio` (default `16 / 9`) — the
11346
+ viewport's aspect ratio.
11347
+
11348
+ ```html
11349
+ <lyra-browser-frame status="streaming" url="https://example.com" .pings=${pings}
11350
+ @lyra-take-over=${(e) => setController(e.detail.controller)} @lyra-stop=${() => stopSession()}
11351
+ ></lyra-browser-frame>
11352
+ ```
11353
+
11354
+ ## `lyra-artifact-panel`
11355
+
11356
+ Shell around one agent-generated artifact: a title/kind header, a preview↔code toggle, version
11357
+ navigation with restore, a streaming indicator, and built-in copy/download actions. Renders none of
11358
+ the artifact itself — content is slotted. No content rendering of its own (slots own it), no
11359
+ dialog/dock chrome (compose `lyra-dialog`/`lyra-dock-panel`/`lyra-split`), no version storage or
11360
+ diffing (host state; diffs via `lyra-diff-view`), no code editing (`lyra-code-editor`).
11361
+
11362
+ **Properties:** `label: string = ''` — the artifact's title, shown in the header. `kind: string = ''`
11363
+ — a short kind label (e.g. `document`, `code`), shown as a badge next to `label`. `view: 'preview' |
11364
+ 'code' = 'preview'` (reflected) — which slot is currently visible. `versions: ArtifactVersion[] = []`
11365
+ (attribute: false, each `{ id, label? }`) — the artifact's version history, oldest first; the last
11366
+ entry is the latest version. `activeVersionId: string | null = null` (attribute
11367
+ `active-version-id`) — the currently viewed version's id, or `null` for "the latest version."
11368
+ `streaming: boolean = false` (reflected) — whether the artifact is still being generated; sets
11369
+ `aria-busy` on the body and shows a text indicator (not animated, so it stays legible under reduced
11370
+ motion). `copyText: string = ''` (attribute `copy-text`) — the text copied to the clipboard by the
11371
+ copy button; empty hides the button. `downloadSrc: string = ''` (attribute `download-src`) — the
11372
+ download URL, sanitized through `safeMediaSrc()`; empty hides the button. `downloadName: string =
11373
+ ''` (attribute `download-name`) — the suggested filename reported in the `lyra-download` event
11374
+ detail.
11375
+
11376
+ **Slots:** default — preview-view content (markdown/html-viewer/browser-frame/image). `code` —
11377
+ code-view content (typically a `lyra-code-block`); the preview/code toggle only renders once this
11378
+ slot has assigned content. `actions` — extra header controls, rendered between the version
11379
+ navigation and the built-in copy/download buttons.
11380
+
11381
+ **Events:** `lyra-view-change` (`detail: { view }`), `lyra-version-change` (`detail: { versionId }`,
11382
+ fired when the previous/next navigation moves to a different version), `lyra-restore` (`detail: {
11383
+ versionId }`, fired by the restore-this-version button; mutates nothing itself), `lyra-copy`
11384
+ (`detail: { text }`, after a best-effort clipboard write), `lyra-download` (`detail: { filename,
11385
+ src? }`, with the sanitized download URL).
11386
+
11387
+ **CSS parts:** `base`, `header`, `label`, `kind`, `view-toggle` (rendered only once the `code` slot
11388
+ has content), `view-button` (carries `data-view="preview"` or `data-view="code"`), `version-nav`
11389
+ (rendered only once `versions` is non-empty), `version-previous`, `version-next`, `version-position`
11390
+ (the "Version N of M" text), `restore-button` (rendered only while the active version isn't the
11391
+ latest), `actions`, `copy-button` (rendered only while `copyText` is non-empty), `download-button`
11392
+ (rendered only while `downloadSrc` is non-empty), `body`, `streaming-indicator` (rendered only while
11393
+ `streaming`).
11394
+
11395
+ ```html
11396
+ <lyra-artifact-panel label="report.md" kind="document" .versions=${versions}
11397
+ @lyra-restore=${(e) => restoreVersion(e.detail.versionId)}>
11398
+ <lyra-markdown .content=${markdown}></lyra-markdown>
11399
+ <lyra-code-block slot="code" language="markdown" .code=${markdown}></lyra-code-block>
11400
+ </lyra-artifact-panel>
11401
+ ```
11402
+
11403
+ ## `lyra-widget-renderer`
11404
+
11405
+ Renders an agent-streamed declarative JSON widget tree through an allowlisted `type -> lyra tag`
11406
+ registry: safe generative UI with exactly one action event out. A mapped node's real element is
11407
+ created via `document.createElement()` with every prop assigned as a plain JS property (never
11408
+ `setAttribute`, never `innerHTML`), and reused by key across a re-resolve so a mapped widget's own
11409
+ internal state (an open `<details>`, focus, scroll position) survives a streamed `tree` update.
11410
+ Built-in `row`/`col`/`text` structural nodes render through ordinary nested templates instead. Not a
11411
+ form runtime (no input/select/form types in the default registry), no expression language or
11412
+ data-binding, no remote widget/schema fetching, and it never renders arbitrary HTML or navigates (no
11413
+ `href` props are allowlisted anywhere).
11414
+
11415
+ **Exported types:** `WidgetNode { type: string; id?: string; props?: Record<string, unknown>;
11416
+ children?: (WidgetNode | string)[]; slot?: string; actionId?: string; payload?: unknown }` — `id` is
11417
+ a stable reconciliation key (falling back to a structural path), `slot` is honored only when the
11418
+ parent type allowlists it, `actionId` arms the type's declared action trigger, and `payload` is
11419
+ echoed back in `lyra-widget-action`.
11420
+
11421
+ **Properties:** `tree: WidgetNode | null = null` (property only) — the declarative widget tree to
11422
+ render; `null` renders an empty base. `registry?: WidgetTypeRegistry` (attribute: false) — a
11423
+ per-instance override of the module-level default registry.
11424
+
11425
+ **Registry module (`widget-renderer/registry.js`):** `registerWidgetType(type, def)` registers (or
11426
+ overwrites) a type in the default registry; `def: WidgetTypeDefinition { tag?: string; props?:
11427
+ Record<string, 'string' | 'number' | 'boolean'>; forcedProps?: Record<string, unknown>; slots?:
11428
+ string[]; action?: { event: string } }` — `tag` is resolved prefix-aware, `props` is a prop allowlist
11429
+ (a prop absent here, or whose runtime type doesn't match, is silently skipped — never assigned),
11430
+ `forcedProps` always apply and are never overridable by `WidgetNode.props`, `slots` allowlists child
11431
+ `slot` names (a disallowed one renders unslotted rather than being dropped), and `action.event` is
11432
+ the native/custom DOM event that arms `lyra-widget-action` when a node also sets `actionId`.
11433
+ `getDefaultWidgetTypeRegistry()` returns the module-level registry `registerWidgetType()` writes to.
11434
+
11435
+ **Default registry** (populated by the side-effect entry's `registerDefaultWidgetTypes()`): `text`
11436
+ (plain text node), `row`/`col` (internal flex wrappers; props `gap: 's'|'m'|'l'`, `align:
11437
+ 'start'|'center'|'end'|'stretch'`, `justify: 'start'|'center'|'end'|'between'`), `card` →
11438
+ `lyra-card` (`appearance`), `badge` → `lyra-badge` (`variant`), `button` → `lyra-button` (`variant`,
11439
+ `appearance`, `size`, `disabled`, `loading`; action: `click`), `stat` → `lyra-stat` (`label`,
11440
+ `value`, `unit`, `variant`, `caption`, `sub`), `result-card` → `lyra-result-card` (`title`),
11441
+ `result-field` → `lyra-result-field` (`label`, `value`), `markdown` → `lyra-markdown` (`content`;
11442
+ forced `{ sanitize: true }`), `image` → `lyra-media-card` (`src`, `alt`, `filename`; forced `{ kind:
11443
+ 'image' }`).
11444
+
11445
+ **Events:** `lyra-widget-action` — `detail: { actionId, payload }`, the single bubbling action
11446
+ channel. `lyra-render-error` — `detail: { error }`, the root value was structurally unusable
11447
+ (non-object, or the depth/size caps made it empty).
11448
+
11449
+ **CSS parts:** `base` (the root wrapper, `display: contents`), `row`, `col`, `text` (built-in
11450
+ structural nodes only — a mapped lyra component exposes its own parts instead).
11451
+
11452
+ Caps: depth 32, 5,000 nodes — excess is skipped with a deduped `console.warn` per type/prop per
11453
+ instance. Reconciliation is keyed by `id ?? structural path`, so a streamed re-send patches in
11454
+ place and user state (an open `<details>`, focus, scroll) survives.
11455
+
11456
+ ```ts
11457
+ registerWidgetType('sparkline', { tag: tag('sparkline'), props: { data: 'string' } });
11458
+ ```
11459
+ ```html
11460
+ <lyra-widget-renderer .tree=${msg.widget}
11461
+ @lyra-widget-action=${(e) => sendToAgent(e.detail.actionId, e.detail.payload)}
11462
+ ></lyra-widget-renderer>
11463
+ ```
11464
+
11465
+ **Optional peer deps:** none new — the default-registry entry directly imports the eight mapped
11466
+ components (`markdown` keeps its own `marked`/`dompurify` optional-peer fallback). A host wanting a
11467
+ leaner dependency graph registers a custom registry (via the `registry` property) and imports only
11468
+ the components it maps.
11469
+
11470
+ ## `lyra-voice-picker`
11471
+
11472
+ A TTS voice selector over a host-supplied `catalog`, mirroring `lyra-model-select`'s
11473
+ closed-dropdown/free-text-combobox dual mode, stale-value handling, and form-association verbatim
11474
+ (see that section for the full mode-switching contract this one shares), extended with a
11475
+ TTS-agnostic preview affordance. Preview is event-first: `lyra-preview-request` always fires first
11476
+ and is cancelable — left un-prevented, a `previewUrl` plays through one internal native `<audio>`
11477
+ (validated by `safeMediaSrc()` first); `preventDefault()` or no URL leaves playback to the host's own
11478
+ TTS. Requesting the same voice while it's already playing internally stops it instead of
11479
+ re-requesting; requesting a different voice switches. Does not synthesize speech, fetch catalogs, or
11480
+ persist selection; not a persona picker; `lyra-model-select` stays for LLMs.
11481
+
11482
+ **Exported types:** `LyraVoiceCatalogEntry { id: string; label: string; language?: string;
11483
+ description?: string; previewUrl?: string }` — `language`/`description` render as a quiet
11484
+ `[part="option-meta"]` second line. `LyraVoiceCatalog = string[] | LyraVoiceCatalogEntry[]` —
11485
+ homogeneous, same union contract as `LyraModelCatalog`.
11486
+
11487
+ **Properties:** `provider: string = ''` — informational only (e.g. `'elevenlabs'`); rendered as a
11488
+ small leading badge. `catalog?: LyraVoiceCatalog` (attribute: false) — the full voice list; omit (or
11489
+ leave empty) to fall back to plain free-text entry. `allowCustom: boolean = false` (attribute
11490
+ `allow-custom`, reflected) — let the user type/commit a value that isn't in `catalog`. `preview:
11491
+ boolean = true` (reflected) — whether to render preview affordances at all. `label: string = ''`,
11492
+ `hint: string = ''`, `errorText: string = ''` (attribute `error-text`), `placeholder: string = ''`,
11493
+ `spellcheck: boolean = true` (string-aware converter, same as `lyra-model-select`), `autocapitalize:
11494
+ string = ''`, `autoCorrect: string = ''` (attribute `autocorrect`), `autocomplete: string = 'off'`,
11495
+ `inputMode: string = ''` (attribute `inputmode`), `enterKeyHint: string = ''` (attribute
11496
+ `enterkeyhint`), and `open: boolean = false` (reflected) — all mirror `lyra-model-select`'s
11497
+ identically-named properties.
11498
+
11499
+ **Form association:** hand-rolled via `attachInternals()`, mirroring `lyra-model-select`: `value`
11500
+ getter/setter (the current voice id, `''` when nothing is selected), `name` (reflected), `disabled`
11501
+ (reflected), `required` (reflected — enforced via `internals.setValidity()`).
11502
+
11503
+ **Events:** `lyra-change` — `detail: { value, inCatalog }`. `lyra-preview-request` — `detail: {
11504
+ voiceId, previewUrl? }`, cancelable. `lyra-preview-change` — `detail: { voiceId }`, internal playback
11505
+ started (`voiceId`) or stopped (`null`). Plus mirrored native `input`/`change` and re-dispatched
11506
+ `focus`/`blur` (picker-family contract, same as `lyra-model-select`).
11507
+
11508
+ **Slots:** `hint`, `error`.
11509
+
11510
+ **CSS parts:** `form-control-label`, `trigger` (closed-dropdown mode), `combobox`/`combobox-input`
11511
+ (free-text mode), `provider-badge`, `listbox`, `option`, `option-label`, `option-meta` (the quiet
11512
+ `language · description` second line), `option-badge` (the "not in catalog" badge on a synthetic
11513
+ stale-value row), `option-preview` (a pointer-only per-row preview icon, `tabindex="-1"`,
11514
+ `aria-hidden`), `preview-button` (the standalone, keyboard-reachable preview toggle beside the
11515
+ trigger), `expand-icon`, `empty`, `hint`, `error`.
11516
+
11517
+ ```html
11518
+ <lyra-voice-picker provider="elevenlabs" .catalog=${voices} allow-custom
11519
+ @lyra-change=${(e) => setVoice(e.detail.value)}
11520
+ @lyra-preview-request=${(e) => {
11521
+ if (!e.detail.previewUrl) {
11522
+ e.preventDefault();
11523
+ playSample(e.detail.voiceId);
11524
+ }
11525
+ }}
11526
+ ></lyra-voice-picker>
11527
+ ```
11528
+
11529
+ **Known gotchas:**
11530
+ - Listbox options must not contain tab-focusable controls, so preview is accessible via the
11531
+ standalone `[part="preview-button"]` beside the trigger (previews the active option while open,
11532
+ else the committed value) — the per-row `[part="option-preview"]` icon is a pointer-only
11533
+ duplicate (`tabindex="-1"`, `aria-hidden="true"`).
11534
+ - `catalog` must be homogeneous — the same constraint `lyra-model-select`'s `LyraModelCatalog` union
11535
+ documents.
11536
+
11537
+ ## `lyra-notebook-viewer`
11538
+
11539
+ Read-only Jupyter notebook (nbformat 4.x) renderer, composing existing components per cell.
11540
+ Execution is a hard non-goal. Markdown cells render through `lyra-markdown`, code cells through
11541
+ `lyra-code-block` (using the notebook's kernel language for syntax highlighting), and raw cells as
11542
+ plain preformatted text. A code cell's `execute_result`/`display_data` outputs prefer, in order,
11543
+ `image/png`, `image/jpeg`, `image/svg+xml` (sanitized), `text/html` (sanitized), `application/json`
11544
+ (via `lyra-json-viewer`), then `text/plain`. Stream/error outputs render as plain preformatted text
11545
+ (tinted `danger` for stderr/tracebacks). Sanitizing raw HTML/SVG output markup lazy-loads the
11546
+ optional peer `dompurify`; without it, the output renders a localized notice instead of raw markup.
11547
+ Cells are virtualized through `lyra-virtual-list`. `node-path` anchors resolve `path[0]` as a cell
11548
+ index; `fragment` anchors resolve a cell's own `id`. No execution, no kernels, no editing, no
11549
+ ipywidgets.
11550
+
11551
+ **Properties:** `src: string = ''` — URL to fetch and parse as a notebook; ignored once `notebook` is
11552
+ set. `notebook?: object | string` (property only) — an already-parsed notebook document, or its raw
11553
+ JSON text; wins over `src` and is parsed (and validated) synchronously. `name: string = ''` —
11554
+ accessible label, and matched against a `fragment` anchor's cell id. `outputCollapseLines: number =
11555
+ 40` (attribute `output-collapse-lines`) — a plain-text output longer than this many lines renders
11556
+ collapsed behind a toggle; `0` disables collapsing. `maxHeight: string = ''` (attribute
11557
+ `max-height`) — once set, the notebook scrolls internally past this height. `anchorKinds` is a
11558
+ readonly `['node-path', 'fragment']` (this viewer's supported `LyraAnchor.kind` values for the
11559
+ shared anchor-target contract).
11560
+
11561
+ **Methods:** `search(query)` resolves the match count over cell sources and text outputs — a
11562
+ matching cell counts as one match (empty/whitespace query behaves like `clearSearch()`);
11563
+ `searchNext()`/`searchPrevious()` advance/step back through matches, scrolling to and flashing the
11564
+ target cell; `clearSearch()` clears the query and matches.
11565
+
11566
+ **Events:** `lyra-load` — `detail: { cellCount, language }`, fired once a notebook has been parsed
11567
+ and validated (`language` from `metadata.language_info.name`/`kernelspec.language`, else `''`).
11568
+ `lyra-highlight-activate` — `detail: { id }`. `lyra-search-change` — `detail: { query, matchCount,
11569
+ activeIndex }`. `lyra-render-error` — `detail: { error }`, fetching, parsing, or validating the
11570
+ notebook failed.
11571
+
11572
+ **CSS parts:** `base` (the root scroll container), `cell` (`data-cell-type="code|markdown|raw"`,
11573
+ `data-active`), `cell-gutter` (the `In [n]`/`Out [n]` label column), `cell-source`, `outputs`,
11574
+ `output` (`data-output-type`, `data-stream`), `output-toggle`, `error`, `spinner`.
11575
+
11576
+ **Themeable custom properties:** `--lyra-notebook-viewer-max-height` (default `none`).
11577
+
11578
+ **Optional peer deps:** `marked`+`dompurify` (markdown cells, falls back to plain text per cell),
11579
+ `shiki` (code cells, falls back to unhighlighted), `dompurify` (HTML/SVG outputs, falls back to
11580
+ `text/plain`).
11581
+
11582
+ ```html
11583
+ <lyra-notebook-viewer .notebook=${result} max-height="30rem"
11584
+ @lyra-load=${(e) => console.log(e.detail.cellCount, 'cells')}
11585
+ ></lyra-notebook-viewer>
11586
+ ```
11587
+
11588
+ A notebook major version outside 4.0–4.5, an invalid shape, or more than 2,000 cells renders a
11589
+ localized error and fires `lyra-render-error` instead of the notebook.
11590
+
11591
+ ## `lyra-xml-viewer`
11592
+
11593
+ Collapsible, copyable, `DOMParser`-based tree view for XML documents, mirroring `lyra-json-viewer`'s
11594
+ UX (`collapsed-depth`, `copyable`, structural-path-keyed expand state that survives a same-shape
11595
+ `xml` reassignment) adapted for XML's own node kinds: elements with attributes, text, comments, CDATA
11596
+ sections, and processing instructions. Namespace-literal: qualified names render exactly as authored,
11597
+ with no namespace-URI-aware matching. `DOMParser` never resolves external entities or DTDs, so XXE
11598
+ injection is structurally out of reach. Not `lyra-json-viewer` (JS values); not `lyra-html-viewer`
11599
+ (sanitized *rendered* HTML). No XPath/XSLT evaluation, no editing, no schema validation.
11600
+
11601
+ **Properties:** `src: string = ''` — URL to fetch and parse; ignored once `xml` is set. `xml?:
11602
+ string` (property only) — raw XML text to parse and render; wins over `src`, and setting it parses
11603
+ synchronously. `name: string = ''` — accessible label. `collapsedDepth?: number` (attribute
11604
+ `collapsed-depth`) — elements at or beyond this nesting depth (root = 0) start collapsed. `copyable:
11605
+ boolean = false` (reflected) — shows copy-to-clipboard affordances, one for the whole document plus
11606
+ one per element. `maxHeight: string = ''` (attribute `max-height`). `anchorKinds` is a readonly
11607
+ `['node-path']` (this viewer's supported `LyraAnchor.kind` values for the shared anchor-target
11608
+ contract) — each numeric path segment is the 0-based index within the parent's *element* children,
11609
+ and an optional trailing string segment `'@attrName'` addresses one attribute.
11610
+
11611
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring search over
11612
+ every element's tag name, attribute names/values, and own text (empty/whitespace query behaves like
11613
+ `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches (wrapping);
11614
+ `clearSearch()` clears the query and matches.
11615
+
11616
+ **Events:** `lyra-copy` — `detail: { text }`. `lyra-search-change` — `detail: { query, matchCount,
11617
+ activeIndex }`. `lyra-render-error` — `detail: { error }`, fetching or parsing failed, including a
11618
+ parse error or exceeding the node cap.
11619
+
11620
+ **CSS parts:** `base`, `toolbar` (the whole-document copy button row, only when `copyable`),
11621
+ `copy-button` (the whole-document one, or a per-node one), `tree`, `node` (`data-active` while it's
11622
+ the resolved anchor target, `data-match`, `data-active-match`), `tag` (`data-match`), `attribute`,
11623
+ `attribute-name`, `attribute-value` (`data-match`), `text` (`data-match`), `comment`, `cdata`, `pi`,
11624
+ `toggle` (an element's expand/collapse button, hidden but present for row alignment on leaf/empty
11625
+ elements), `error`, `spinner`.
11626
+
11627
+ **Themeable custom properties:** `--lyra-xml-viewer-max-height` (default `none`).
11628
+
11629
+ ```html
11630
+ <lyra-xml-viewer .xml=${payload} collapsed-depth="2" copyable
11631
+ search=${query}
11632
+ ></lyra-xml-viewer>
11633
+ ```
11634
+
11635
+ Node cap: 50,000 — exceeding it renders the localized `xmlViewerTooManyNodes` error instead of the
11636
+ tree.
11637
+
11638
+ ## `lyra-geojson-view`
11639
+
11640
+ Internal document-registry bridge that fetches, validates, and renders a GeoJSON file through
11641
+ `<lyra-map>`'s `dataLayers` — not a documented public tag: excluded from the README/llms family
11642
+ tables, present in the generated manifest since a defined custom element is technically reachable.
11643
+ The document registry matches `application/geo+json` and `.geojson` filenames.
11644
+
11645
+ Validates the parsed JSON is a `Feature`/`FeatureCollection`/bare geometry (one of `Point`,
11646
+ `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon`, `GeometryCollection`) before
11647
+ rendering; anything else renders the localized `geojsonViewInvalid` error. On success, it walks every
11648
+ coordinate to compute a bounding box and fits a `center`/`zoom` to it (a Web-Mercator-fit
11649
+ approximation weighting latitude span ~2x, with 40% padding), then hands the parsed value to
11650
+ `<lyra-map>` as a single `dataLayers` entry (`sourceId: 'lyra-geojson'`). When the optional
11651
+ `maplibre-gl` peer isn't installed, it falls back to a status line plus a `<lyra-json-viewer
11652
+ collapsed-depth="2">` of the raw value instead of the map.
11653
+
11654
+ **Properties:** `src: string = ''` — URL to fetch and parse. `name: string = ''` — accessible label,
11655
+ used as `<lyra-map>`'s `label` and the root's `aria-label` (falling back to the localized
11656
+ `geojsonViewLabel` when unset).
11657
+
11658
+ **Events:** `lyra-render-error` — `detail: { error }` — fetch, parse, or shape-validation failure.
11659
+
11660
+ **CSS parts:** `base` (the root container), `status` (the feature-count status line, `role="status"`,
11661
+ shown only in the `<lyra-map>` path), `missing-library` (the missing-`maplibre-gl` callout shown
11662
+ alongside the `lyra-json-viewer` fallback), `error` (the error region, `role="alert"`), `spinner`
11663
+ (the loading status region).
11664
+
11665
+ Registered by importing `geojson-view/geojson-view.js` directly — not part of the root barrel, the
11666
+ same as `lyra-map`/`lyra-graph`, since it depends on the same optional `maplibre-gl` peer. Remote
11667
+ resources are capped at 25 MB; exceeding it surfaces the localized `documentPreviewResourceTooLarge`
11668
+ message instead of the map.