@aceshooting/lyra-ui 3.7.0 → 3.8.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 (1315) hide show
  1. package/README.md +108 -3
  2. package/custom-elements.json +89972 -41448
  3. package/dist/components/activity-feed/activity-feed.class.d.ts +111 -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 +292 -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 +110 -0
  579. package/dist/components/graph/graph-canvas.d.ts.map +1 -0
  580. package/dist/components/graph/graph-canvas.js +175 -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 +447 -2
  591. package/dist/components/graph/graph.class.d.ts.map +1 -1
  592. package/dist/components/graph/graph.class.js +1700 -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 +100 -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 +3 -2
  653. package/dist/components/input/input.class.d.ts.map +1 -1
  654. package/dist/components/input/input.class.js +2 -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.class.d.ts +191 -4
  687. package/dist/components/markdown/markdown.class.d.ts.map +1 -1
  688. package/dist/components/markdown/markdown.class.js +584 -11
  689. package/dist/components/markdown/markdown.class.js.map +1 -1
  690. package/dist/components/markdown/markdown.styles.d.ts.map +1 -1
  691. package/dist/components/markdown/markdown.styles.js +53 -0
  692. package/dist/components/markdown/markdown.styles.js.map +1 -1
  693. package/dist/components/media-card/media-card.styles.d.ts.map +1 -1
  694. package/dist/components/media-card/media-card.styles.js +6 -2
  695. package/dist/components/media-card/media-card.styles.js.map +1 -1
  696. package/dist/components/mention-popover/mention-popover.styles.d.ts.map +1 -1
  697. package/dist/components/mention-popover/mention-popover.styles.js +6 -3
  698. package/dist/components/mention-popover/mention-popover.styles.js.map +1 -1
  699. package/dist/components/message-actions/message-actions.class.d.ts +112 -0
  700. package/dist/components/message-actions/message-actions.class.d.ts.map +1 -0
  701. package/dist/components/message-actions/message-actions.class.js +277 -0
  702. package/dist/components/message-actions/message-actions.class.js.map +1 -0
  703. package/dist/components/message-actions/message-actions.d.ts +4 -0
  704. package/dist/components/message-actions/message-actions.d.ts.map +1 -0
  705. package/dist/components/message-actions/message-actions.js +7 -0
  706. package/dist/components/message-actions/message-actions.js.map +1 -0
  707. package/dist/components/message-actions/message-actions.styles.d.ts +2 -0
  708. package/dist/components/message-actions/message-actions.styles.d.ts.map +1 -0
  709. package/dist/components/message-actions/message-actions.styles.js +66 -0
  710. package/dist/components/message-actions/message-actions.styles.js.map +1 -0
  711. package/dist/components/message-feedback/message-feedback.class.d.ts +91 -0
  712. package/dist/components/message-feedback/message-feedback.class.d.ts.map +1 -0
  713. package/dist/components/message-feedback/message-feedback.class.js +266 -0
  714. package/dist/components/message-feedback/message-feedback.class.js.map +1 -0
  715. package/dist/components/message-feedback/message-feedback.d.ts +2 -0
  716. package/dist/components/message-feedback/message-feedback.d.ts.map +1 -0
  717. package/dist/components/message-feedback/message-feedback.js +5 -0
  718. package/dist/components/message-feedback/message-feedback.js.map +1 -0
  719. package/dist/components/message-feedback/message-feedback.styles.d.ts +2 -0
  720. package/dist/components/message-feedback/message-feedback.styles.d.ts.map +1 -0
  721. package/dist/components/message-feedback/message-feedback.styles.js +133 -0
  722. package/dist/components/message-feedback/message-feedback.styles.js.map +1 -0
  723. package/dist/components/mind-map/mind-map-layout.d.ts +52 -0
  724. package/dist/components/mind-map/mind-map-layout.d.ts.map +1 -0
  725. package/dist/components/mind-map/mind-map-layout.js +69 -0
  726. package/dist/components/mind-map/mind-map-layout.js.map +1 -0
  727. package/dist/components/mind-map/mind-map.class.d.ts +83 -0
  728. package/dist/components/mind-map/mind-map.class.d.ts.map +1 -0
  729. package/dist/components/mind-map/mind-map.class.js +252 -0
  730. package/dist/components/mind-map/mind-map.class.js.map +1 -0
  731. package/dist/components/mind-map/mind-map.d.ts +2 -0
  732. package/dist/components/mind-map/mind-map.d.ts.map +1 -0
  733. package/dist/components/mind-map/mind-map.js +5 -0
  734. package/dist/components/mind-map/mind-map.js.map +1 -0
  735. package/dist/components/mind-map/mind-map.styles.d.ts +2 -0
  736. package/dist/components/mind-map/mind-map.styles.d.ts.map +1 -0
  737. package/dist/components/mind-map/mind-map.styles.js +43 -0
  738. package/dist/components/mind-map/mind-map.styles.js.map +1 -0
  739. package/dist/components/model-select/model-select.class.d.ts +1 -0
  740. package/dist/components/model-select/model-select.class.d.ts.map +1 -1
  741. package/dist/components/model-select/model-select.class.js +13 -0
  742. package/dist/components/model-select/model-select.class.js.map +1 -1
  743. package/dist/components/mutation-observer/mutation-observer.class.d.ts +1 -0
  744. package/dist/components/mutation-observer/mutation-observer.class.d.ts.map +1 -1
  745. package/dist/components/mutation-observer/mutation-observer.class.js +15 -0
  746. package/dist/components/mutation-observer/mutation-observer.class.js.map +1 -1
  747. package/dist/components/neighbor-list/neighbor-list.class.d.ts +70 -0
  748. package/dist/components/neighbor-list/neighbor-list.class.d.ts.map +1 -0
  749. package/dist/components/neighbor-list/neighbor-list.class.js +177 -0
  750. package/dist/components/neighbor-list/neighbor-list.class.js.map +1 -0
  751. package/dist/components/neighbor-list/neighbor-list.d.ts +4 -0
  752. package/dist/components/neighbor-list/neighbor-list.d.ts.map +1 -0
  753. package/dist/components/neighbor-list/neighbor-list.js +7 -0
  754. package/dist/components/neighbor-list/neighbor-list.js.map +1 -0
  755. package/dist/components/neighbor-list/neighbor-list.styles.d.ts +2 -0
  756. package/dist/components/neighbor-list/neighbor-list.styles.d.ts.map +1 -0
  757. package/dist/components/neighbor-list/neighbor-list.styles.js +79 -0
  758. package/dist/components/neighbor-list/neighbor-list.styles.js.map +1 -0
  759. package/dist/components/node-palette/node-palette.class.d.ts +82 -0
  760. package/dist/components/node-palette/node-palette.class.d.ts.map +1 -0
  761. package/dist/components/node-palette/node-palette.class.js +213 -0
  762. package/dist/components/node-palette/node-palette.class.js.map +1 -0
  763. package/dist/components/node-palette/node-palette.d.ts +2 -0
  764. package/dist/components/node-palette/node-palette.d.ts.map +1 -0
  765. package/dist/components/node-palette/node-palette.js +5 -0
  766. package/dist/components/node-palette/node-palette.js.map +1 -0
  767. package/dist/components/node-palette/node-palette.styles.d.ts +2 -0
  768. package/dist/components/node-palette/node-palette.styles.d.ts.map +1 -0
  769. package/dist/components/node-palette/node-palette.styles.js +74 -0
  770. package/dist/components/node-palette/node-palette.styles.js.map +1 -0
  771. package/dist/components/notebook-viewer/dompurify-loader.d.ts +7 -0
  772. package/dist/components/notebook-viewer/dompurify-loader.d.ts.map +1 -0
  773. package/dist/components/notebook-viewer/dompurify-loader.js +23 -0
  774. package/dist/components/notebook-viewer/dompurify-loader.js.map +1 -0
  775. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts +164 -0
  776. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts.map +1 -0
  777. package/dist/components/notebook-viewer/notebook-viewer.class.js +442 -0
  778. package/dist/components/notebook-viewer/notebook-viewer.class.js.map +1 -0
  779. package/dist/components/notebook-viewer/notebook-viewer.d.ts +6 -0
  780. package/dist/components/notebook-viewer/notebook-viewer.d.ts.map +1 -0
  781. package/dist/components/notebook-viewer/notebook-viewer.js +21 -0
  782. package/dist/components/notebook-viewer/notebook-viewer.js.map +1 -0
  783. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts +2 -0
  784. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts.map +1 -0
  785. package/dist/components/notebook-viewer/notebook-viewer.styles.js +79 -0
  786. package/dist/components/notebook-viewer/notebook-viewer.styles.js.map +1 -0
  787. package/dist/components/overlay/overlay.styles.d.ts.map +1 -1
  788. package/dist/components/overlay/overlay.styles.js +17 -5
  789. package/dist/components/overlay/overlay.styles.js.map +1 -1
  790. package/dist/components/overlay/popover.class.d.ts +2 -0
  791. package/dist/components/overlay/popover.class.d.ts.map +1 -1
  792. package/dist/components/overlay/popover.class.js +10 -2
  793. package/dist/components/overlay/popover.class.js.map +1 -1
  794. package/dist/components/overlay/tooltip.class.d.ts +4 -0
  795. package/dist/components/overlay/tooltip.class.d.ts.map +1 -1
  796. package/dist/components/overlay/tooltip.class.js +21 -6
  797. package/dist/components/overlay/tooltip.class.js.map +1 -1
  798. package/dist/components/page-rail/page-rail.class.d.ts +99 -0
  799. package/dist/components/page-rail/page-rail.class.d.ts.map +1 -0
  800. package/dist/components/page-rail/page-rail.class.js +279 -0
  801. package/dist/components/page-rail/page-rail.class.js.map +1 -0
  802. package/dist/components/page-rail/page-rail.d.ts +2 -0
  803. package/dist/components/page-rail/page-rail.d.ts.map +1 -0
  804. package/dist/components/page-rail/page-rail.js +5 -0
  805. package/dist/components/page-rail/page-rail.js.map +1 -0
  806. package/dist/components/page-rail/page-rail.styles.d.ts +2 -0
  807. package/dist/components/page-rail/page-rail.styles.d.ts.map +1 -0
  808. package/dist/components/page-rail/page-rail.styles.js +85 -0
  809. package/dist/components/page-rail/page-rail.styles.js.map +1 -0
  810. package/dist/components/pagination/pagination.class.d.ts +5 -0
  811. package/dist/components/pagination/pagination.class.d.ts.map +1 -1
  812. package/dist/components/pagination/pagination.class.js +11 -9
  813. package/dist/components/pagination/pagination.class.js.map +1 -1
  814. package/dist/components/path-strip/path-strip.class.d.ts +61 -0
  815. package/dist/components/path-strip/path-strip.class.d.ts.map +1 -0
  816. package/dist/components/path-strip/path-strip.class.js +164 -0
  817. package/dist/components/path-strip/path-strip.class.js.map +1 -0
  818. package/dist/components/path-strip/path-strip.d.ts +3 -0
  819. package/dist/components/path-strip/path-strip.d.ts.map +1 -0
  820. package/dist/components/path-strip/path-strip.js +6 -0
  821. package/dist/components/path-strip/path-strip.js.map +1 -0
  822. package/dist/components/path-strip/path-strip.styles.d.ts +2 -0
  823. package/dist/components/path-strip/path-strip.styles.d.ts.map +1 -0
  824. package/dist/components/path-strip/path-strip.styles.js +62 -0
  825. package/dist/components/path-strip/path-strip.styles.js.map +1 -0
  826. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts +145 -6
  827. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts.map +1 -1
  828. package/dist/components/pdf-viewer/pdf-viewer.class.js +785 -21
  829. package/dist/components/pdf-viewer/pdf-viewer.class.js.map +1 -1
  830. package/dist/components/pdf-viewer/pdf-viewer.js +7 -1
  831. package/dist/components/pdf-viewer/pdf-viewer.js.map +1 -1
  832. package/dist/components/pdf-viewer/pdf-viewer.styles.d.ts.map +1 -1
  833. package/dist/components/pdf-viewer/pdf-viewer.styles.js +4 -0
  834. package/dist/components/pdf-viewer/pdf-viewer.styles.js.map +1 -1
  835. package/dist/components/phone-input/phone-input.class.d.ts.map +1 -1
  836. package/dist/components/phone-input/phone-input.class.js +5 -1
  837. package/dist/components/phone-input/phone-input.class.js.map +1 -1
  838. package/dist/components/playback/playback.styles.d.ts.map +1 -1
  839. package/dist/components/playback/playback.styles.js +7 -0
  840. package/dist/components/playback/playback.styles.js.map +1 -1
  841. package/dist/components/poll-status/poll-status.class.d.ts +1 -0
  842. package/dist/components/poll-status/poll-status.class.d.ts.map +1 -1
  843. package/dist/components/poll-status/poll-status.class.js +25 -7
  844. package/dist/components/poll-status/poll-status.class.js.map +1 -1
  845. package/dist/components/pptx-viewer/pptx-viewer.styles.d.ts.map +1 -1
  846. package/dist/components/pptx-viewer/pptx-viewer.styles.js +5 -0
  847. package/dist/components/pptx-viewer/pptx-viewer.styles.js.map +1 -1
  848. package/dist/components/progress/progress-bar.class.d.ts +5 -0
  849. package/dist/components/progress/progress-bar.class.d.ts.map +1 -1
  850. package/dist/components/progress/progress-bar.class.js +16 -2
  851. package/dist/components/progress/progress-bar.class.js.map +1 -1
  852. package/dist/components/progress/progress-ring.class.d.ts +5 -0
  853. package/dist/components/progress/progress-ring.class.d.ts.map +1 -1
  854. package/dist/components/progress/progress-ring.class.js +16 -2
  855. package/dist/components/progress/progress-ring.class.js.map +1 -1
  856. package/dist/components/progress/progress.styles.d.ts.map +1 -1
  857. package/dist/components/progress/progress.styles.js +6 -0
  858. package/dist/components/progress/progress.styles.js.map +1 -1
  859. package/dist/components/provenance-panel/provenance-panel.class.d.ts +71 -0
  860. package/dist/components/provenance-panel/provenance-panel.class.d.ts.map +1 -0
  861. package/dist/components/provenance-panel/provenance-panel.class.js +110 -0
  862. package/dist/components/provenance-panel/provenance-panel.class.js.map +1 -0
  863. package/dist/components/provenance-panel/provenance-panel.d.ts +7 -0
  864. package/dist/components/provenance-panel/provenance-panel.d.ts.map +1 -0
  865. package/dist/components/provenance-panel/provenance-panel.js +10 -0
  866. package/dist/components/provenance-panel/provenance-panel.js.map +1 -0
  867. package/dist/components/provenance-panel/provenance-panel.styles.d.ts +2 -0
  868. package/dist/components/provenance-panel/provenance-panel.styles.d.ts.map +1 -0
  869. package/dist/components/provenance-panel/provenance-panel.styles.js +45 -0
  870. package/dist/components/provenance-panel/provenance-panel.styles.js.map +1 -0
  871. package/dist/components/push-to-talk/push-to-talk.class.d.ts +145 -0
  872. package/dist/components/push-to-talk/push-to-talk.class.d.ts.map +1 -0
  873. package/dist/components/push-to-talk/push-to-talk.class.js +478 -0
  874. package/dist/components/push-to-talk/push-to-talk.class.js.map +1 -0
  875. package/dist/components/push-to-talk/push-to-talk.d.ts +3 -0
  876. package/dist/components/push-to-talk/push-to-talk.d.ts.map +1 -0
  877. package/dist/components/push-to-talk/push-to-talk.js +6 -0
  878. package/dist/components/push-to-talk/push-to-talk.js.map +1 -0
  879. package/dist/components/push-to-talk/push-to-talk.styles.d.ts +2 -0
  880. package/dist/components/push-to-talk/push-to-talk.styles.d.ts.map +1 -0
  881. package/dist/components/push-to-talk/push-to-talk.styles.js +79 -0
  882. package/dist/components/push-to-talk/push-to-talk.styles.js.map +1 -0
  883. package/dist/components/radio/radio.class.d.ts +1 -0
  884. package/dist/components/radio/radio.class.d.ts.map +1 -1
  885. package/dist/components/radio/radio.class.js +4 -0
  886. package/dist/components/radio/radio.class.js.map +1 -1
  887. package/dist/components/random-content/random-content.class.d.ts +3 -1
  888. package/dist/components/random-content/random-content.class.d.ts.map +1 -1
  889. package/dist/components/random-content/random-content.class.js +7 -4
  890. package/dist/components/random-content/random-content.class.js.map +1 -1
  891. package/dist/components/rating/rating.class.d.ts +8 -0
  892. package/dist/components/rating/rating.class.d.ts.map +1 -1
  893. package/dist/components/rating/rating.class.js +34 -8
  894. package/dist/components/rating/rating.class.js.map +1 -1
  895. package/dist/components/rubric-form/rubric-form.class.d.ts +195 -0
  896. package/dist/components/rubric-form/rubric-form.class.d.ts.map +1 -0
  897. package/dist/components/rubric-form/rubric-form.class.js +495 -0
  898. package/dist/components/rubric-form/rubric-form.class.js.map +1 -0
  899. package/dist/components/rubric-form/rubric-form.d.ts +9 -0
  900. package/dist/components/rubric-form/rubric-form.d.ts.map +1 -0
  901. package/dist/components/rubric-form/rubric-form.js +12 -0
  902. package/dist/components/rubric-form/rubric-form.js.map +1 -0
  903. package/dist/components/rubric-form/rubric-form.styles.d.ts +2 -0
  904. package/dist/components/rubric-form/rubric-form.styles.d.ts.map +1 -0
  905. package/dist/components/rubric-form/rubric-form.styles.js +90 -0
  906. package/dist/components/rubric-form/rubric-form.styles.js.map +1 -0
  907. package/dist/components/scroller/scroller.class.d.ts +6 -0
  908. package/dist/components/scroller/scroller.class.d.ts.map +1 -1
  909. package/dist/components/scroller/scroller.class.js +14 -4
  910. package/dist/components/scroller/scroller.class.js.map +1 -1
  911. package/dist/components/scroller/scroller.styles.d.ts.map +1 -1
  912. package/dist/components/scroller/scroller.styles.js +18 -0
  913. package/dist/components/scroller/scroller.styles.js.map +1 -1
  914. package/dist/components/segmented/segmented.class.d.ts +1 -0
  915. package/dist/components/segmented/segmented.class.d.ts.map +1 -1
  916. package/dist/components/segmented/segmented.class.js +1 -0
  917. package/dist/components/segmented/segmented.class.js.map +1 -1
  918. package/dist/components/segmented/segmented.styles.d.ts.map +1 -1
  919. package/dist/components/segmented/segmented.styles.js +21 -3
  920. package/dist/components/segmented/segmented.styles.js.map +1 -1
  921. package/dist/components/sequence-strip/sequence-strip.class.d.ts +62 -0
  922. package/dist/components/sequence-strip/sequence-strip.class.d.ts.map +1 -0
  923. package/dist/components/sequence-strip/sequence-strip.class.js +102 -0
  924. package/dist/components/sequence-strip/sequence-strip.class.js.map +1 -0
  925. package/dist/components/sequence-strip/sequence-strip.d.ts +2 -0
  926. package/dist/components/sequence-strip/sequence-strip.d.ts.map +1 -0
  927. package/dist/components/sequence-strip/sequence-strip.js +5 -0
  928. package/dist/components/sequence-strip/sequence-strip.js.map +1 -0
  929. package/dist/components/sequence-strip/sequence-strip.styles.d.ts +2 -0
  930. package/dist/components/sequence-strip/sequence-strip.styles.d.ts.map +1 -0
  931. package/dist/components/sequence-strip/sequence-strip.styles.js +62 -0
  932. package/dist/components/sequence-strip/sequence-strip.styles.js.map +1 -0
  933. package/dist/components/skeleton/skeleton.styles.d.ts.map +1 -1
  934. package/dist/components/skeleton/skeleton.styles.js +7 -0
  935. package/dist/components/skeleton/skeleton.styles.js.map +1 -1
  936. package/dist/components/slider/slider.class.d.ts +6 -1
  937. package/dist/components/slider/slider.class.d.ts.map +1 -1
  938. package/dist/components/slider/slider.class.js +23 -6
  939. package/dist/components/slider/slider.class.js.map +1 -1
  940. package/dist/components/slider/slider.styles.d.ts.map +1 -1
  941. package/dist/components/slider/slider.styles.js +15 -0
  942. package/dist/components/slider/slider.styles.js.map +1 -1
  943. package/dist/components/source-picker/source-picker.class.d.ts +78 -0
  944. package/dist/components/source-picker/source-picker.class.d.ts.map +1 -0
  945. package/dist/components/source-picker/source-picker.class.js +305 -0
  946. package/dist/components/source-picker/source-picker.class.js.map +1 -0
  947. package/dist/components/source-picker/source-picker.d.ts +5 -0
  948. package/dist/components/source-picker/source-picker.d.ts.map +1 -0
  949. package/dist/components/source-picker/source-picker.js +8 -0
  950. package/dist/components/source-picker/source-picker.js.map +1 -0
  951. package/dist/components/source-picker/source-picker.styles.d.ts +2 -0
  952. package/dist/components/source-picker/source-picker.styles.d.ts.map +1 -0
  953. package/dist/components/source-picker/source-picker.styles.js +80 -0
  954. package/dist/components/source-picker/source-picker.styles.js.map +1 -0
  955. package/dist/components/span-waterfall/span-waterfall.class.d.ts +70 -0
  956. package/dist/components/span-waterfall/span-waterfall.class.d.ts.map +1 -0
  957. package/dist/components/span-waterfall/span-waterfall.class.js +307 -0
  958. package/dist/components/span-waterfall/span-waterfall.class.js.map +1 -0
  959. package/dist/components/span-waterfall/span-waterfall.d.ts +4 -0
  960. package/dist/components/span-waterfall/span-waterfall.d.ts.map +1 -0
  961. package/dist/components/span-waterfall/span-waterfall.js +7 -0
  962. package/dist/components/span-waterfall/span-waterfall.js.map +1 -0
  963. package/dist/components/span-waterfall/span-waterfall.styles.d.ts +2 -0
  964. package/dist/components/span-waterfall/span-waterfall.styles.d.ts.map +1 -0
  965. package/dist/components/span-waterfall/span-waterfall.styles.js +130 -0
  966. package/dist/components/span-waterfall/span-waterfall.styles.js.map +1 -0
  967. package/dist/components/sparkline/sparkline.class.d.ts.map +1 -1
  968. package/dist/components/sparkline/sparkline.class.js +17 -7
  969. package/dist/components/sparkline/sparkline.class.js.map +1 -1
  970. package/dist/components/split/split.class.d.ts +13 -0
  971. package/dist/components/split/split.class.d.ts.map +1 -1
  972. package/dist/components/split/split.class.js +24 -4
  973. package/dist/components/split/split.class.js.map +1 -1
  974. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js +1 -1
  975. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js.map +1 -1
  976. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts +93 -3
  977. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts.map +1 -1
  978. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js +241 -9
  979. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js.map +1 -1
  980. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js +10 -1
  981. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js.map +1 -1
  982. package/dist/components/stack-trace/stack-trace-parse.d.ts +22 -0
  983. package/dist/components/stack-trace/stack-trace-parse.d.ts.map +1 -0
  984. package/dist/components/stack-trace/stack-trace-parse.js +194 -0
  985. package/dist/components/stack-trace/stack-trace-parse.js.map +1 -0
  986. package/dist/components/stack-trace/stack-trace.class.d.ts +68 -0
  987. package/dist/components/stack-trace/stack-trace.class.d.ts.map +1 -0
  988. package/dist/components/stack-trace/stack-trace.class.js +193 -0
  989. package/dist/components/stack-trace/stack-trace.class.js.map +1 -0
  990. package/dist/components/stack-trace/stack-trace.d.ts +3 -0
  991. package/dist/components/stack-trace/stack-trace.d.ts.map +1 -0
  992. package/dist/components/stack-trace/stack-trace.js +6 -0
  993. package/dist/components/stack-trace/stack-trace.js.map +1 -0
  994. package/dist/components/stack-trace/stack-trace.styles.d.ts +2 -0
  995. package/dist/components/stack-trace/stack-trace.styles.d.ts.map +1 -0
  996. package/dist/components/stack-trace/stack-trace.styles.js +101 -0
  997. package/dist/components/stack-trace/stack-trace.styles.js.map +1 -0
  998. package/dist/components/stat/stat.class.d.ts +10 -1
  999. package/dist/components/stat/stat.class.d.ts.map +1 -1
  1000. package/dist/components/stat/stat.class.js +22 -7
  1001. package/dist/components/stat/stat.class.js.map +1 -1
  1002. package/dist/components/stepper/stepper.class.d.ts +5 -0
  1003. package/dist/components/stepper/stepper.class.d.ts.map +1 -1
  1004. package/dist/components/stepper/stepper.class.js +9 -1
  1005. package/dist/components/stepper/stepper.class.js.map +1 -1
  1006. package/dist/components/stream-status/stream-status.class.d.ts.map +1 -1
  1007. package/dist/components/stream-status/stream-status.class.js +9 -1
  1008. package/dist/components/stream-status/stream-status.class.js.map +1 -1
  1009. package/dist/components/streaming-text/streaming-text.class.d.ts +6 -0
  1010. package/dist/components/streaming-text/streaming-text.class.d.ts.map +1 -1
  1011. package/dist/components/streaming-text/streaming-text.class.js +22 -3
  1012. package/dist/components/streaming-text/streaming-text.class.js.map +1 -1
  1013. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts +54 -0
  1014. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts.map +1 -0
  1015. package/dist/components/suggestion-chips/suggestion-chips.class.js +120 -0
  1016. package/dist/components/suggestion-chips/suggestion-chips.class.js.map +1 -0
  1017. package/dist/components/suggestion-chips/suggestion-chips.d.ts +3 -0
  1018. package/dist/components/suggestion-chips/suggestion-chips.d.ts.map +1 -0
  1019. package/dist/components/suggestion-chips/suggestion-chips.js +6 -0
  1020. package/dist/components/suggestion-chips/suggestion-chips.js.map +1 -0
  1021. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts +2 -0
  1022. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts.map +1 -0
  1023. package/dist/components/suggestion-chips/suggestion-chips.styles.js +60 -0
  1024. package/dist/components/suggestion-chips/suggestion-chips.styles.js.map +1 -0
  1025. package/dist/components/svg-viewer/svg-viewer.class.d.ts +34 -0
  1026. package/dist/components/svg-viewer/svg-viewer.class.d.ts.map +1 -1
  1027. package/dist/components/svg-viewer/svg-viewer.class.js +88 -1
  1028. package/dist/components/svg-viewer/svg-viewer.class.js.map +1 -1
  1029. package/dist/components/svg-viewer/svg-viewer.js +1 -0
  1030. package/dist/components/svg-viewer/svg-viewer.js.map +1 -1
  1031. package/dist/components/svg-viewer/svg-viewer.styles.d.ts.map +1 -1
  1032. package/dist/components/svg-viewer/svg-viewer.styles.js +18 -0
  1033. package/dist/components/svg-viewer/svg-viewer.styles.js.map +1 -1
  1034. package/dist/components/swatch-picker/swatch-picker.class.d.ts +18 -2
  1035. package/dist/components/swatch-picker/swatch-picker.class.d.ts.map +1 -1
  1036. package/dist/components/swatch-picker/swatch-picker.class.js +17 -3
  1037. package/dist/components/swatch-picker/swatch-picker.class.js.map +1 -1
  1038. package/dist/components/swatch-picker/swatch-picker.styles.d.ts.map +1 -1
  1039. package/dist/components/swatch-picker/swatch-picker.styles.js +84 -8
  1040. package/dist/components/swatch-picker/swatch-picker.styles.js.map +1 -1
  1041. package/dist/components/table/table.class.d.ts +85 -5
  1042. package/dist/components/table/table.class.d.ts.map +1 -1
  1043. package/dist/components/table/table.class.js +254 -41
  1044. package/dist/components/table/table.class.js.map +1 -1
  1045. package/dist/components/table/table.styles.d.ts.map +1 -1
  1046. package/dist/components/table/table.styles.js +35 -0
  1047. package/dist/components/table/table.styles.js.map +1 -1
  1048. package/dist/components/tabs/tabs.class.d.ts +6 -0
  1049. package/dist/components/tabs/tabs.class.d.ts.map +1 -1
  1050. package/dist/components/tabs/tabs.class.js +10 -1
  1051. package/dist/components/tabs/tabs.class.js.map +1 -1
  1052. package/dist/components/tabs/tabs.styles.d.ts.map +1 -1
  1053. package/dist/components/tabs/tabs.styles.js +15 -0
  1054. package/dist/components/tabs/tabs.styles.js.map +1 -1
  1055. package/dist/components/task-list/task-list.class.d.ts +89 -0
  1056. package/dist/components/task-list/task-list.class.d.ts.map +1 -0
  1057. package/dist/components/task-list/task-list.class.js +271 -0
  1058. package/dist/components/task-list/task-list.class.js.map +1 -0
  1059. package/dist/components/task-list/task-list.d.ts +2 -0
  1060. package/dist/components/task-list/task-list.d.ts.map +1 -0
  1061. package/dist/components/task-list/task-list.js +5 -0
  1062. package/dist/components/task-list/task-list.js.map +1 -0
  1063. package/dist/components/task-list/task-list.styles.d.ts +2 -0
  1064. package/dist/components/task-list/task-list.styles.d.ts.map +1 -0
  1065. package/dist/components/task-list/task-list.styles.js +134 -0
  1066. package/dist/components/task-list/task-list.styles.js.map +1 -0
  1067. package/dist/components/terminal/terminal.class.d.ts +150 -0
  1068. package/dist/components/terminal/terminal.class.d.ts.map +1 -0
  1069. package/dist/components/terminal/terminal.class.js +565 -0
  1070. package/dist/components/terminal/terminal.class.js.map +1 -0
  1071. package/dist/components/terminal/terminal.d.ts +2 -0
  1072. package/dist/components/terminal/terminal.d.ts.map +1 -0
  1073. package/dist/components/terminal/terminal.js +5 -0
  1074. package/dist/components/terminal/terminal.js.map +1 -0
  1075. package/dist/components/terminal/terminal.styles.d.ts +2 -0
  1076. package/dist/components/terminal/terminal.styles.d.ts.map +1 -0
  1077. package/dist/components/terminal/terminal.styles.js +77 -0
  1078. package/dist/components/terminal/terminal.styles.js.map +1 -0
  1079. package/dist/components/test-results/test-results.class.d.ts +99 -0
  1080. package/dist/components/test-results/test-results.class.d.ts.map +1 -0
  1081. package/dist/components/test-results/test-results.class.js +276 -0
  1082. package/dist/components/test-results/test-results.class.js.map +1 -0
  1083. package/dist/components/test-results/test-results.d.ts +2 -0
  1084. package/dist/components/test-results/test-results.d.ts.map +1 -0
  1085. package/dist/components/test-results/test-results.js +5 -0
  1086. package/dist/components/test-results/test-results.js.map +1 -0
  1087. package/dist/components/test-results/test-results.styles.d.ts +2 -0
  1088. package/dist/components/test-results/test-results.styles.d.ts.map +1 -0
  1089. package/dist/components/test-results/test-results.styles.js +118 -0
  1090. package/dist/components/test-results/test-results.styles.js.map +1 -0
  1091. package/dist/components/textarea/textarea.class.d.ts.map +1 -1
  1092. package/dist/components/textarea/textarea.class.js +4 -0
  1093. package/dist/components/textarea/textarea.class.js.map +1 -1
  1094. package/dist/components/thinking-panel/thinking-panel.class.d.ts +6 -0
  1095. package/dist/components/thinking-panel/thinking-panel.class.d.ts.map +1 -1
  1096. package/dist/components/thinking-panel/thinking-panel.class.js +12 -2
  1097. package/dist/components/thinking-panel/thinking-panel.class.js.map +1 -1
  1098. package/dist/components/thread-list/thread-list.class.d.ts +130 -0
  1099. package/dist/components/thread-list/thread-list.class.d.ts.map +1 -0
  1100. package/dist/components/thread-list/thread-list.class.js +480 -0
  1101. package/dist/components/thread-list/thread-list.class.js.map +1 -0
  1102. package/dist/components/thread-list/thread-list.d.ts +5 -0
  1103. package/dist/components/thread-list/thread-list.d.ts.map +1 -0
  1104. package/dist/components/thread-list/thread-list.js +8 -0
  1105. package/dist/components/thread-list/thread-list.js.map +1 -0
  1106. package/dist/components/thread-list/thread-list.styles.d.ts +2 -0
  1107. package/dist/components/thread-list/thread-list.styles.d.ts.map +1 -0
  1108. package/dist/components/thread-list/thread-list.styles.js +81 -0
  1109. package/dist/components/thread-list/thread-list.styles.js.map +1 -0
  1110. package/dist/components/time-range/time-range.class.d.ts.map +1 -1
  1111. package/dist/components/time-range/time-range.class.js +3 -3
  1112. package/dist/components/time-range/time-range.class.js.map +1 -1
  1113. package/dist/components/timeline/timeline-item.class.d.ts.map +1 -1
  1114. package/dist/components/timeline/timeline-item.class.js +2 -1
  1115. package/dist/components/timeline/timeline-item.class.js.map +1 -1
  1116. package/dist/components/toast/toast-item.class.d.ts +8 -0
  1117. package/dist/components/toast/toast-item.class.d.ts.map +1 -1
  1118. package/dist/components/toast/toast-item.class.js +14 -2
  1119. package/dist/components/toast/toast-item.class.js.map +1 -1
  1120. package/dist/components/toast/toast-item.styles.d.ts.map +1 -1
  1121. package/dist/components/toast/toast-item.styles.js +2 -0
  1122. package/dist/components/toast/toast-item.styles.js.map +1 -1
  1123. package/dist/components/token-input/token-input.class.d.ts +29 -3
  1124. package/dist/components/token-input/token-input.class.d.ts.map +1 -1
  1125. package/dist/components/token-input/token-input.class.js +41 -13
  1126. package/dist/components/token-input/token-input.class.js.map +1 -1
  1127. package/dist/components/token-input/token-input.styles.d.ts.map +1 -1
  1128. package/dist/components/token-input/token-input.styles.js +6 -1
  1129. package/dist/components/token-input/token-input.styles.js.map +1 -1
  1130. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts +6 -0
  1131. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts.map +1 -1
  1132. package/dist/components/tool-call-chip/tool-call-chip.class.js +15 -4
  1133. package/dist/components/tool-call-chip/tool-call-chip.class.js.map +1 -1
  1134. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts +6 -0
  1135. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts.map +1 -1
  1136. package/dist/components/tool-result-dialog/tool-result-dialog.class.js +12 -3
  1137. package/dist/components/tool-result-dialog/tool-result-dialog.class.js.map +1 -1
  1138. package/dist/components/tour/tour.class.d.ts +6 -3
  1139. package/dist/components/tour/tour.class.d.ts.map +1 -1
  1140. package/dist/components/tour/tour.class.js +56 -20
  1141. package/dist/components/tour/tour.class.js.map +1 -1
  1142. package/dist/components/trace-tree/span.d.ts +26 -0
  1143. package/dist/components/trace-tree/span.d.ts.map +1 -0
  1144. package/dist/components/trace-tree/span.js +2 -0
  1145. package/dist/components/trace-tree/span.js.map +1 -0
  1146. package/dist/components/trace-tree/trace-tree.class.d.ts +85 -0
  1147. package/dist/components/trace-tree/trace-tree.class.d.ts.map +1 -0
  1148. package/dist/components/trace-tree/trace-tree.class.js +443 -0
  1149. package/dist/components/trace-tree/trace-tree.class.js.map +1 -0
  1150. package/dist/components/trace-tree/trace-tree.d.ts +5 -0
  1151. package/dist/components/trace-tree/trace-tree.d.ts.map +1 -0
  1152. package/dist/components/trace-tree/trace-tree.js +8 -0
  1153. package/dist/components/trace-tree/trace-tree.js.map +1 -0
  1154. package/dist/components/trace-tree/trace-tree.styles.d.ts +2 -0
  1155. package/dist/components/trace-tree/trace-tree.styles.d.ts.map +1 -0
  1156. package/dist/components/trace-tree/trace-tree.styles.js +186 -0
  1157. package/dist/components/trace-tree/trace-tree.styles.js.map +1 -0
  1158. package/dist/components/transcript-feed/transcript-feed.class.d.ts +89 -0
  1159. package/dist/components/transcript-feed/transcript-feed.class.d.ts.map +1 -0
  1160. package/dist/components/transcript-feed/transcript-feed.class.js +188 -0
  1161. package/dist/components/transcript-feed/transcript-feed.class.js.map +1 -0
  1162. package/dist/components/transcript-feed/transcript-feed.d.ts +2 -0
  1163. package/dist/components/transcript-feed/transcript-feed.d.ts.map +1 -0
  1164. package/dist/components/transcript-feed/transcript-feed.js +5 -0
  1165. package/dist/components/transcript-feed/transcript-feed.js.map +1 -0
  1166. package/dist/components/transcript-feed/transcript-feed.styles.d.ts +2 -0
  1167. package/dist/components/transcript-feed/transcript-feed.styles.d.ts.map +1 -0
  1168. package/dist/components/transcript-feed/transcript-feed.styles.js +94 -0
  1169. package/dist/components/transcript-feed/transcript-feed.styles.js.map +1 -0
  1170. package/dist/components/tree/tree-node.class.d.ts +25 -4
  1171. package/dist/components/tree/tree-node.class.d.ts.map +1 -1
  1172. package/dist/components/tree/tree-node.class.js +61 -11
  1173. package/dist/components/tree/tree-node.class.js.map +1 -1
  1174. package/dist/components/tree/tree-node.styles.d.ts.map +1 -1
  1175. package/dist/components/tree/tree-node.styles.js +34 -5
  1176. package/dist/components/tree/tree-node.styles.js.map +1 -1
  1177. package/dist/components/tree/tree.class.d.ts +9 -0
  1178. package/dist/components/tree/tree.class.d.ts.map +1 -1
  1179. package/dist/components/tree/tree.class.js.map +1 -1
  1180. package/dist/components/usage-badge/usage-badge.class.d.ts +78 -0
  1181. package/dist/components/usage-badge/usage-badge.class.d.ts.map +1 -0
  1182. package/dist/components/usage-badge/usage-badge.class.js +237 -0
  1183. package/dist/components/usage-badge/usage-badge.class.js.map +1 -0
  1184. package/dist/components/usage-badge/usage-badge.d.ts +2 -0
  1185. package/dist/components/usage-badge/usage-badge.d.ts.map +1 -0
  1186. package/dist/components/usage-badge/usage-badge.js +5 -0
  1187. package/dist/components/usage-badge/usage-badge.js.map +1 -0
  1188. package/dist/components/usage-badge/usage-badge.styles.d.ts +2 -0
  1189. package/dist/components/usage-badge/usage-badge.styles.d.ts.map +1 -0
  1190. package/dist/components/usage-badge/usage-badge.styles.js +62 -0
  1191. package/dist/components/usage-badge/usage-badge.styles.js.map +1 -0
  1192. package/dist/components/virtual-list/virtual-list.class.d.ts +62 -0
  1193. package/dist/components/virtual-list/virtual-list.class.d.ts.map +1 -1
  1194. package/dist/components/virtual-list/virtual-list.class.js +123 -8
  1195. package/dist/components/virtual-list/virtual-list.class.js.map +1 -1
  1196. package/dist/components/voice-picker/voice-picker.class.d.ts +241 -0
  1197. package/dist/components/voice-picker/voice-picker.class.d.ts.map +1 -0
  1198. package/dist/components/voice-picker/voice-picker.class.js +808 -0
  1199. package/dist/components/voice-picker/voice-picker.class.js.map +1 -0
  1200. package/dist/components/voice-picker/voice-picker.d.ts +2 -0
  1201. package/dist/components/voice-picker/voice-picker.d.ts.map +1 -0
  1202. package/dist/components/voice-picker/voice-picker.js +5 -0
  1203. package/dist/components/voice-picker/voice-picker.js.map +1 -0
  1204. package/dist/components/voice-picker/voice-picker.styles.d.ts +2 -0
  1205. package/dist/components/voice-picker/voice-picker.styles.d.ts.map +1 -0
  1206. package/dist/components/voice-picker/voice-picker.styles.js +272 -0
  1207. package/dist/components/voice-picker/voice-picker.styles.js.map +1 -0
  1208. package/dist/components/widget-renderer/default-registry.d.ts +14 -0
  1209. package/dist/components/widget-renderer/default-registry.d.ts.map +1 -0
  1210. package/dist/components/widget-renderer/default-registry.js +43 -0
  1211. package/dist/components/widget-renderer/default-registry.js.map +1 -0
  1212. package/dist/components/widget-renderer/registry.d.ts +31 -0
  1213. package/dist/components/widget-renderer/registry.d.ts.map +1 -0
  1214. package/dist/components/widget-renderer/registry.js +23 -0
  1215. package/dist/components/widget-renderer/registry.js.map +1 -0
  1216. package/dist/components/widget-renderer/resolve.d.ts +48 -0
  1217. package/dist/components/widget-renderer/resolve.d.ts.map +1 -0
  1218. package/dist/components/widget-renderer/resolve.js +122 -0
  1219. package/dist/components/widget-renderer/resolve.js.map +1 -0
  1220. package/dist/components/widget-renderer/widget-renderer.class.d.ts +67 -0
  1221. package/dist/components/widget-renderer/widget-renderer.class.d.ts.map +1 -0
  1222. package/dist/components/widget-renderer/widget-renderer.class.js +175 -0
  1223. package/dist/components/widget-renderer/widget-renderer.class.js.map +1 -0
  1224. package/dist/components/widget-renderer/widget-renderer.d.ts +5 -0
  1225. package/dist/components/widget-renderer/widget-renderer.d.ts.map +1 -0
  1226. package/dist/components/widget-renderer/widget-renderer.js +10 -0
  1227. package/dist/components/widget-renderer/widget-renderer.js.map +1 -0
  1228. package/dist/components/widget-renderer/widget-renderer.styles.d.ts +2 -0
  1229. package/dist/components/widget-renderer/widget-renderer.styles.d.ts.map +1 -0
  1230. package/dist/components/widget-renderer/widget-renderer.styles.js +14 -0
  1231. package/dist/components/widget-renderer/widget-renderer.styles.js.map +1 -0
  1232. package/dist/components/word-cloud/word-cloud-layout.d.ts +4 -0
  1233. package/dist/components/word-cloud/word-cloud-layout.d.ts.map +1 -1
  1234. package/dist/components/word-cloud/word-cloud-layout.js +3 -2
  1235. package/dist/components/word-cloud/word-cloud-layout.js.map +1 -1
  1236. package/dist/components/word-cloud/word-cloud.class.d.ts.map +1 -1
  1237. package/dist/components/word-cloud/word-cloud.class.js +11 -3
  1238. package/dist/components/word-cloud/word-cloud.class.js.map +1 -1
  1239. package/dist/components/xml-viewer/xml-viewer.class.d.ts +135 -0
  1240. package/dist/components/xml-viewer/xml-viewer.class.d.ts.map +1 -0
  1241. package/dist/components/xml-viewer/xml-viewer.class.js +0 -0
  1242. package/dist/components/xml-viewer/xml-viewer.class.js.map +1 -0
  1243. package/dist/components/xml-viewer/xml-viewer.d.ts +2 -0
  1244. package/dist/components/xml-viewer/xml-viewer.d.ts.map +1 -0
  1245. package/dist/components/xml-viewer/xml-viewer.js +20 -0
  1246. package/dist/components/xml-viewer/xml-viewer.js.map +1 -0
  1247. package/dist/components/xml-viewer/xml-viewer.styles.d.ts +2 -0
  1248. package/dist/components/xml-viewer/xml-viewer.styles.d.ts.map +1 -0
  1249. package/dist/components/xml-viewer/xml-viewer.styles.js +156 -0
  1250. package/dist/components/xml-viewer/xml-viewer.styles.js.map +1 -0
  1251. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts +14 -2
  1252. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts.map +1 -1
  1253. package/dist/components/zoomable-frame/zoomable-frame.class.js +30 -14
  1254. package/dist/components/zoomable-frame/zoomable-frame.class.js.map +1 -1
  1255. package/dist/internal/anchor-target.d.ts +49 -0
  1256. package/dist/internal/anchor-target.d.ts.map +1 -0
  1257. package/dist/internal/anchor-target.js +255 -0
  1258. package/dist/internal/anchor-target.js.map +1 -0
  1259. package/dist/internal/ansi.d.ts +35 -0
  1260. package/dist/internal/ansi.d.ts.map +1 -0
  1261. package/dist/internal/ansi.js +210 -0
  1262. package/dist/internal/ansi.js.map +1 -0
  1263. package/dist/internal/cell-range.d.ts +19 -0
  1264. package/dist/internal/cell-range.d.ts.map +1 -0
  1265. package/dist/internal/cell-range.js +69 -0
  1266. package/dist/internal/cell-range.js.map +1 -0
  1267. package/dist/internal/intl-cache.d.ts +33 -0
  1268. package/dist/internal/intl-cache.d.ts.map +1 -0
  1269. package/dist/internal/intl-cache.js +0 -0
  1270. package/dist/internal/intl-cache.js.map +1 -0
  1271. package/dist/internal/layered-layout.d.ts +44 -0
  1272. package/dist/internal/layered-layout.d.ts.map +1 -0
  1273. package/dist/internal/layered-layout.js +172 -0
  1274. package/dist/internal/layered-layout.js.map +1 -0
  1275. package/dist/internal/localization.d.ts +12 -1
  1276. package/dist/internal/localization.d.ts.map +1 -1
  1277. package/dist/internal/localization.js +366 -4
  1278. package/dist/internal/localization.js.map +1 -1
  1279. package/dist/internal/lyra-element.d.ts +10 -1
  1280. package/dist/internal/lyra-element.d.ts.map +1 -1
  1281. package/dist/internal/lyra-element.js +19 -1
  1282. package/dist/internal/lyra-element.js.map +1 -1
  1283. package/dist/internal/root-registration-allowlist.d.ts +2 -2
  1284. package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
  1285. package/dist/internal/root-registration-allowlist.js +54 -0
  1286. package/dist/internal/root-registration-allowlist.js.map +1 -1
  1287. package/dist/internal/slugger.d.ts +11 -0
  1288. package/dist/internal/slugger.d.ts.map +1 -0
  1289. package/dist/internal/slugger.js +45 -0
  1290. package/dist/internal/slugger.js.map +1 -0
  1291. package/dist/internal/text-highlights.d.ts +21 -0
  1292. package/dist/internal/text-highlights.d.ts.map +1 -0
  1293. package/dist/internal/text-highlights.js +172 -0
  1294. package/dist/internal/text-highlights.js.map +1 -0
  1295. package/dist/internal/text-quote.d.ts +53 -0
  1296. package/dist/internal/text-quote.d.ts.map +1 -0
  1297. package/dist/internal/text-quote.js +326 -0
  1298. package/dist/internal/text-quote.js.map +1 -0
  1299. package/dist/internal/tokens.styles.d.ts.map +1 -1
  1300. package/dist/internal/tokens.styles.js +49 -0
  1301. package/dist/internal/tokens.styles.js.map +1 -1
  1302. package/dist/internal/viewer-search.d.ts +18 -0
  1303. package/dist/internal/viewer-search.d.ts.map +1 -0
  1304. package/dist/internal/viewer-search.js +21 -0
  1305. package/dist/internal/viewer-search.js.map +1 -0
  1306. package/dist/lyra.d.ts +133 -2
  1307. package/dist/lyra.d.ts.map +1 -1
  1308. package/dist/lyra.js +107 -0
  1309. package/dist/lyra.js.map +1 -1
  1310. package/llms-full.txt +2640 -102
  1311. package/llms.txt +27 -1
  1312. package/package.json +157 -31
  1313. package/vscode-css-data.json +217 -0
  1314. package/vscode-html-data.json +5233 -2249
  1315. package/web-types.json +5674 -2506
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
  ---
@@ -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,26 @@ 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. `communities: GraphCommunity[] = []` (attribute:
2792
+ false) draws one translucent convex-hull blob per entry behind links/nodes. `focusId: string | null =
2793
+ null` (attribute `focus-id`) tracks a persistent focus ring (`[part="focus-halo"]`) around one node;
2794
+ `focusNode(id, options?)` and `fit(options?)` are the imperative camera-tween counterparts (pan/zoom
2795
+ to a node, or to fit the whole graph), both resolving once the tween settles.
2619
2796
 
2620
2797
  ---
2621
2798
 
@@ -2697,46 +2874,856 @@ through `lyra-tree`'s light DOM.
2697
2874
 
2698
2875
  **Slots:** none.
2699
2876
 
2700
- **CSS parts:** `row`, `toggle`, `icon`, `content`, `label`, `description`, `badge`, `group`. `icon` is
2701
- `aria-hidden="true"`; `content` groups the primary label and optional wrapping secondary
2702
- description while preserving one interactive treeitem per row.
2877
+ **CSS parts:** `row`, `toggle`, `icon`, `content`, `label`, `description`, `badge`, `group`. `icon` is
2878
+ `aria-hidden="true"`; `content` groups the primary label and optional wrapping secondary
2879
+ description while preserving one interactive treeitem per row.
2880
+
2881
+ **Themeable custom properties:** `--lyra-tree-depth` (internal, set inline per row for
2882
+ indentation), plus the shared tokens listed above.
2883
+
2884
+ **Optional peer deps:** none.
2885
+
2886
+ ```html
2887
+ <lyra-tree></lyra-tree>
2888
+ <script>
2889
+ document.querySelector('lyra-tree').data = [
2890
+ {
2891
+ id: '1',
2892
+ label: 'Root',
2893
+ description: 'Two child documents',
2894
+ accessibleLabel: 'Root, two child documents',
2895
+ icon: document.createTextNode('◇'),
2896
+ children: [{ id: '1a', label: 'Child A' }, { id: '1b', label: 'Child B', badge: 3 }],
2897
+ },
2898
+ ];
2899
+ </script>
2900
+ ```
2901
+
2902
+ **Known gotchas:**
2903
+ - all four previously-known ARIA gaps in this pair are fixed: the treeitem row is now genuinely
2904
+ keyboard-operable with a roving tabindex and full arrow-key navigation (not just the expand/collapse
2905
+ button); the expanded-children `role="group"` is now a real DOM descendant of its `role="treeitem"`
2906
+ host rather than a shadow-DOM sibling; by-id reconciliation (preserving `expanded` state across
2907
+ data reassignment) now applies at every depth via a keyed `repeat()`, not just depth 0; and
2908
+ `role="tree"` now has an accessible name via the new `label` property.
2909
+ - `lyra-tree`'s `getUpdateComplete()` cascades into every currently-known descendant
2910
+ `<lyra-tree-node>`'s own `updateComplete` (see `update-cascade.ts`) so that code awaiting the
2911
+ tree's `updateComplete` (e.g. after `focusNode()`) doesn't run before an arbitrarily-nested node has
2912
+ actually finished rendering its pushed-down `activeId`/`tabIndex` — one more pending update per
2913
+ depth level, otherwise.
2914
+ - row enrichment is intentionally structured rather than an unrestricted renderer: use `icon`,
2915
+ `label`, `description`, `badge`, and `accessibleLabel`. This keeps the host as the single
2916
+ `role="treeitem"` interaction target and preserves the APG keyboard model.
2917
+
2918
+ ---
2919
+
2920
+ # Flow canvas
2921
+
2922
+ ## `lyra-flow-canvas`
2923
+
2924
+ A pannable/zoomable DAG workflow canvas: positions HTML node cards, draws SVG edges between their
2925
+ handles, runs a shared layered auto-layout for unpositioned nodes, and owns all selection/drag/
2926
+ connect interaction as controlled events. Readonly (viewer) by default; opt into editor gestures
2927
+ individually via `nodes-draggable`, `connectable`, `droppable`. Never mutates `nodes` or `edges`
2928
+ itself — every edit intent is an event the host applies, mirroring `lyra-stepper`/`lyra-table`'s
2929
+ controlled-component contract.
2930
+
2931
+ **Properties:**
2932
+ - `nodes: FlowNode[] = []` (attribute: false) — `FlowNode { id: string; type?: string; position?: {
2933
+ x, y }; data?: Record<string, unknown>; accessibleLabel?: string; inputs?: FlowHandle[]; outputs?:
2934
+ FlowHandle[] }`; a node with no `position` is placed by the layered auto-layout, and `data.label`/
2935
+ `data.description` feed the default `<lyra-flow-node>` card when no matching light-DOM child exists
2936
+ - `edges: FlowEdge[] = []` (attribute: false) — `FlowEdge { id: string; source: string; target:
2937
+ string; sourceHandle?: string; targetHandle?: string; label?: string; tone?: 'accent' | 'success' |
2938
+ 'warning' | 'danger' | 'neutral' }` (source/target are node ids; `label` draws at the edge midpoint,
2939
+ unlike `lyra-graph`'s spoken-only `GraphLink.label`)
2940
+ - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — downstream layout/handle axis
2941
+ - `nodesDraggable: boolean = false` (attribute `nodes-draggable`)
2942
+ - `connectable: boolean = false`
2943
+ - `droppable: boolean = false` — accepts drops carrying the `FLOW_PALETTE_MIME_TYPE` payload a
2944
+ `lyra-node-palette` drag sets, emitting `lyra-node-add`
2945
+ - `locked: boolean = false` (reflected) — freezes pan/zoom/drag/connect without touching the other
2946
+ gesture flags
2947
+ - `selectedNodeIds: string[] = []`, `selectedEdgeIds: string[] = []` (attribute: false) — controlled;
2948
+ the host assigns these back from `lyra-selection-change`
2949
+ - `minZoom: number = 0.25` (attribute `min-zoom`), `maxZoom: number = 2` (attribute `max-zoom`)
2950
+ - `grid: number = 8` — snap step in content px for drags/nudges/drop positions (`0` disables
2951
+ snapping); also the dotted background's base spacing
2952
+ - `layerGap: number = 64` (attribute `layer-gap`), `nodeGap: number = 24` (attribute `node-gap`) —
2953
+ auto-layout layer/sibling spacing
2954
+ - `decorations: FlowRunDecorations | null = null` (attribute: false) — `Record<nodeOrEdgeId,
2955
+ FlowRunDecoration>`, `FlowRunDecoration { status: 'pending'|'running'|'success'|'error'|'denied';
2956
+ progress?: number; durationMs?: number; detail?: string }`; pushed onto adopted `lyra-flow-node`
2957
+ cards, typically supplied via a `lyra-flow-run-overlay`
2958
+ - `accessibleLabel: string | null = null` (attribute `aria-label`)
2959
+ - `viewport` (read-only getter) — `{ x, y, zoom }`, the current pan/zoom state
2960
+
2961
+ **Methods:** `setViewport({ x, y, zoom })`, `zoomIn()`, `zoomOut()`, `resetZoom()`,
2962
+ `fit(options?: { padding?: number })` (frames every node), `focusNode(id, options?: { zoom? })`
2963
+ (pans/zooms to one node and moves roving focus onto it), `toContentPoint(clientX, clientY)` (maps a
2964
+ pointer position to content coordinates, RTL-aware), `registerCompanion(cb: (snapshot:
2965
+ FlowStructureSnapshot) => void): () => void` — the subscription `lyra-flow-minimap` uses to read
2966
+ live node/edge/viewport geometry without this canvas ever importing the minimap.
2967
+
2968
+ **Events:** `lyra-node-click` (`detail: { id }`), `lyra-edge-click` (`detail: { id, source, target
2969
+ }`), `lyra-selection-change` (`detail: { nodeIds, edgeIds }`), `lyra-node-move` (`detail: { id,
2970
+ position, previous }`), `lyra-connect` (`detail: { source, target, sourceHandle, targetHandle }`),
2971
+ `lyra-node-add` (`detail: { type, position }`, from a palette drop), `lyra-selection-delete`
2972
+ (`detail: { nodeIds, edgeIds }`), `lyra-viewport-change` (`detail: { x, y, zoom }`),
2973
+ `lyra-layout-change` (`detail: { positions }`, fired after an auto-layout pass places previously
2974
+ unpositioned nodes).
2975
+
2976
+ **Slots:** default (`lyra-flow-node` children adopted by `node-id`; a non-matching child is ignored
2977
+ with a console warning), `top-start`, `top-end` (floating corner overlays), `bottom-start` (e.g.
2978
+ `lyra-flow-controls`), `bottom-end` (e.g. `lyra-flow-minimap`).
2979
+
2980
+ **CSS parts:** `base`, `viewport`, `background`, `edges`, `edge`, `edge-label`, `arrowhead`, `stub`
2981
+ (a dangling-edge stub line), `connection-line` (in-progress connect gesture), `node`, `empty`,
2982
+ `live-region`, `edge-list` (a visually hidden list of every edge).
2983
+
2984
+ **Themeable custom properties:** `--lyra-flow-canvas-grid-size` (default `8px`, dotted background
2985
+ spacing), `--lyra-flow-canvas-march-duration` (default `var(--lyra-transition-ambient)`, running-edge
2986
+ march animation duration).
2987
+
2988
+ **Optional peer deps:** none.
2989
+
2990
+ ```html
2991
+ <lyra-flow-canvas id="canvas" nodes-draggable connectable droppable style="height:480px"></lyra-flow-canvas>
2992
+ <lyra-flow-controls slot="bottom-start" for="canvas"></lyra-flow-controls>
2993
+ <lyra-flow-minimap slot="bottom-end" for="canvas"></lyra-flow-minimap>
2994
+ <script>
2995
+ const canvas = document.getElementById('canvas');
2996
+ canvas.nodes = [
2997
+ { id: 'a', data: { label: 'Fetch' } },
2998
+ { id: 'b', data: { label: 'Transform' } },
2999
+ ];
3000
+ canvas.edges = [{ id: 'a-b', source: 'a', target: 'b' }];
3001
+ canvas.addEventListener('lyra-node-move', (e) => {
3002
+ canvas.nodes = canvas.nodes.map((n) => (n.id === e.detail.id ? { ...n, position: e.detail.position } : n));
3003
+ });
3004
+ </script>
3005
+ ```
3006
+
3007
+ **Known gotchas:**
3008
+ - Fully controlled: `nodes`/`edges`/`selectedNodeIds`/`selectedEdgeIds` are never mutated
3009
+ internally — `lyra-node-move`, `lyra-selection-change`, `lyra-connect`, `lyra-node-add`, and
3010
+ `lyra-selection-delete` are all requests the host applies back, same contract as `lyra-table`.
3011
+ - Auto-layout (via the dependency-free `layeredLayout()` util) only ever positions nodes that are
3012
+ missing an explicit `position`; a node the host has already positioned is left exactly where it is
3013
+ and used as a fixed anchor for the rest of the layout pass.
3014
+ - `droppable` only accepts drags carrying the exact `FLOW_PALETTE_MIME_TYPE` MIME type a
3015
+ `lyra-node-palette` drag sets — the two components can never disagree on the payload shape because
3016
+ they share one exported constant.
3017
+ - Pan/drag/zoom track the pointer's physical direction; under an RTL ancestor the pan and node-drag
3018
+ deltas are mirrored so content still visually follows the cursor, matching every other
3019
+ RTL-mirrored surface in this library.
3020
+
3021
+ ---
3022
+
3023
+ ## `lyra-flow-node`
3024
+
3025
+ The card a workflow node renders as: header/body/toolbar chrome, tool-lifecycle status tones, and
3026
+ the named connection-handle elements edges anchor to. Used as `lyra-flow-canvas`'s default card and
3027
+ as a slotted override; also renders standalone (palette previews, docs). Purely presentational —
3028
+ activation, selection, movement, and connection are all `lyra-flow-canvas` events; this component
3029
+ owns none of that.
3030
+
3031
+ **Properties:**
3032
+ - `nodeId: string = ''` (attribute `node-id`)
3033
+ - `heading: string = ''`
3034
+ - `status: 'pending' | 'running' | 'success' | 'error' | 'denied' | null = null` (reflected)
3035
+ - `progress: number | null = null` — renders a determinate `[part="progress"]` bar when set
3036
+ - `statusDetail: string = ''` (attribute `status-detail`) — appended to the status line
3037
+ - `durationMs: number | null = null` (attribute `duration-ms`) — formatted into the status line
3038
+ - `selected: boolean = false` (reflected)
3039
+ - `inputs: FlowHandle[] = [{ id: 'in' }]`, `outputs: FlowHandle[] = [{ id: 'out' }]` (attribute:
3040
+ false) — `FlowHandle { id: string; label?: string }`
3041
+ - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — which physical edge handles
3042
+ render on; mirrors the adopting canvas's own `orientation`
3043
+
3044
+ **Events:** none — purely presentational, activation/drag/connect all live on `lyra-flow-canvas`.
3045
+
3046
+ **Slots:** default (body content), `icon` (leading header glyph), `header` (replaces the built-in
3047
+ heading row entirely), `toolbar` (action row at the block-end edge).
3048
+
3049
+ **CSS parts:** `base`, `header`, `icon`, `heading`, `status` (never color-only — always paired with
3050
+ text), `progress`, `body`, `toolbar`, `handle` (every handle dot), `handle-input`, `handle-output`.
3051
+
3052
+ **Themeable custom properties:** `--lyra-flow-node-min-inline-size` (default `11rem`).
3053
+
3054
+ **Optional peer deps:** none.
3055
+
3056
+ ```html
3057
+ <lyra-flow-node node-id="a" heading="Fetch" status="running" progress="40"></lyra-flow-node>
3058
+ ```
3059
+
3060
+ **Known gotchas:**
3061
+ - A running node's card pulses (`?data-pulse`) unless `prefers-reduced-motion` is set — the same
3062
+ reduced-motion exception every animated surface in this library follows.
3063
+ - `status` drives a status chip with a localized label plus `statusDetail`/`durationMs`, never a
3064
+ color-only indicator.
3065
+
3066
+ ---
3067
+
3068
+ ## `lyra-flow-minimap`
3069
+
3070
+ A corner overview map of a `lyra-flow-canvas`: scaled node rectangles plus a draggable viewport
3071
+ rectangle, for orientation and fast navigation on canvases larger than the screen. Draws no edges
3072
+ (nodes only, matching the React Flow/n8n minimap convention) and never reads `nodes` itself —
3073
+ geometry always comes from the canvas's `registerCompanion()` snapshots, so the two can never
3074
+ disagree.
3075
+
3076
+ **Properties:**
3077
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; when empty, the nearest ancestor canvas
3078
+ is used (the slotted-into-a-corner-slot case, the primary wiring)
3079
+ - `label: string = ''` — accessible name for the map region; falls back to a host `aria-label`, then
3080
+ a localized default
3081
+
3082
+ **Events:** none.
3083
+
3084
+ **Slots:** none.
3085
+
3086
+ **CSS parts:** `base`, `map` (the scaled SVG), `node` (one rect per node), `viewport` (the
3087
+ draggable, focusable view rectangle).
3088
+
3089
+ **Themeable custom properties:** `--lyra-flow-minimap-inline-size` (default `12rem`),
3090
+ `--lyra-flow-minimap-block-size` (default `8rem`).
3091
+
3092
+ **Optional peer deps:** none.
3093
+
3094
+ ```html
3095
+ <lyra-flow-canvas id="canvas" style="height:480px">
3096
+ <lyra-flow-minimap slot="bottom-end" for="canvas"></lyra-flow-minimap>
3097
+ </lyra-flow-canvas>
3098
+ ```
3099
+
3100
+ **Known gotchas:**
3101
+ - Never resolves `nodes`/`edges` on its own — it subscribes to `registerCompanion()` and repaints
3102
+ from whatever snapshot the canvas last pushed, so it can only ever show what the canvas itself
3103
+ currently renders.
3104
+ - Dragging the viewport rectangle calls the canvas's `setViewport()` directly; there's no separate
3105
+ event to wire up.
3106
+
3107
+ ---
3108
+
3109
+ ## `lyra-flow-controls`
3110
+
3111
+ The canvas's button cluster: zoom in/out, fit, and interaction lock, so every flow surface ships the
3112
+ same affordances without hosts rebuilding them. Manipulates only view state, never `nodes`/`edges` —
3113
+ no editing commands live here.
3114
+
3115
+ **Properties:**
3116
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; empty resolves to the nearest ancestor
3117
+ - `orientation: 'vertical' | 'horizontal' = 'vertical'` (reflected) — button-cluster layout axis
3118
+ - `hideLock: boolean = false` (attribute `hide-lock`) — omits the lock/unlock toggle button
3119
+
3120
+ **Events:** none dispatched directly — each button calls the resolved canvas's own `zoomIn()`/
3121
+ `zoomOut()`/`fit()`, or toggles its `locked` property.
3122
+
3123
+ **Slots:** default — extra host buttons appended to the cluster, styled by the same group.
3124
+
3125
+ **CSS parts:** `base` (the `role="group"` wrapper), `zoom-in`, `zoom-out`, `fit`, `lock` (omitted
3126
+ when `hideLock`).
3127
+
3128
+ **Themeable custom properties:** shared tokens only.
3129
+
3130
+ **Optional peer deps:** none.
3131
+
3132
+ ```html
3133
+ <lyra-flow-canvas id="canvas" style="height:480px">
3134
+ <lyra-flow-controls slot="bottom-start" for="canvas"></lyra-flow-controls>
3135
+ </lyra-flow-canvas>
3136
+ ```
3137
+
3138
+ **Known gotchas:**
3139
+ - `for` resolution is identical to `lyra-flow-minimap`/`lyra-flow-run-overlay`: an explicit id, else
3140
+ the nearest ancestor canvas — none of the three companions import `LyraFlowCanvas` as a value, only
3141
+ its types, so registration order between them and the canvas never matters.
3142
+
3143
+ ---
3144
+
3145
+ ## `lyra-node-palette`
3146
+
3147
+ The searchable, categorized node library for workflow editors: drag an item onto a canvas, or place
3148
+ it by keyboard. Never creates nodes or touches a canvas's data itself — the drop/place handshake ends
3149
+ at `lyra-node-add`/`lyra-palette-place`; the host mutates `nodes`. Fully decoupled from
3150
+ `lyra-flow-canvas` (no `for` resolution, unlike the other three companions) — it only needs to agree
3151
+ with a `droppable` canvas on the `FLOW_PALETTE_MIME_TYPE` drag payload shape.
3152
+
3153
+ **Properties:**
3154
+ - `items: PaletteItem[] = []` (attribute: false) — `PaletteItem { type: string; label: string;
3155
+ description?: string; category?: string; keywords?: string[]; icon?: unknown; disabled?: boolean }`;
3156
+ `type` is the `FlowNode.type` a placement/drop creates, `category` groups items under
3157
+ first-appearance-ordered headings, `disabled` renders an item visible but not draggable/placeable
3158
+ - `label: string = ''` — accessible name for the search field/listbox
3159
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — overrides the listbox's
3160
+ computed accessible name; wins over `label` and the localized default, and attribute-reflects
3161
+ from a host-level `aria-label`
3162
+
3163
+ **Events:** `lyra-palette-place` (`detail: { type }`, a pointer click or Enter/Space — the
3164
+ click/keyboard alternative to dragging), `lyra-select` (`detail: { item }`, emitted alongside
3165
+ `lyra-palette-place` on both gestures, carrying the full item).
3166
+
3167
+ **Slots:** `header` (content above the search field, e.g. a heading or tabs), `footer` (content
3168
+ below the list).
3169
+
3170
+ **CSS parts:** `base`, `search`, `list` (the listbox), `group-header`, `item`, `item-icon`,
3171
+ `item-label`, `item-description`, `empty` (no-results message), `live-region` (result-count
3172
+ announcement).
3173
+
3174
+ **Themeable custom properties:** shared tokens only.
3175
+
3176
+ **Optional peer deps:** none.
3177
+
3178
+ ```html
3179
+ <lyra-node-palette id="palette"></lyra-node-palette>
3180
+ <lyra-flow-canvas id="canvas" droppable style="height:480px"></lyra-flow-canvas>
3181
+ <script>
3182
+ document.getElementById('palette').items = [
3183
+ { type: 'http-request', label: 'HTTP Request', category: 'Actions' },
3184
+ { type: 'transform', label: 'Transform', category: 'Actions' },
3185
+ ];
3186
+ document.getElementById('canvas').addEventListener('lyra-node-add', (e) => {
3187
+ console.log('drop payload type:', e.detail.type, e.detail.position);
3188
+ });
3189
+ </script>
3190
+ ```
3191
+
3192
+ **Known gotchas:**
3193
+ - A drag from this palette carries `FLOW_PALETTE_MIME_TYPE` as its `DataTransfer` type — only a
3194
+ `droppable` `lyra-flow-canvas` (or a host reimplementing the same MIME type) accepts it.
3195
+ - Clicking or activating an item by keyboard fires `lyra-palette-place`/`lyra-select` immediately, no
3196
+ drag required — the host decides where the new node lands (there's no pointer position to derive
3197
+ one from on a keyboard placement).
3198
+
3199
+ ---
3200
+
3201
+ ## `lyra-flow-run-overlay`
3202
+
3203
+ Execution-state presentation for a `lyra-flow-canvas`: pushes a `FlowRunDecorations` map into the
3204
+ resolved canvas (the canvas itself renders the node/edge paint) and renders a compact run-summary
3205
+ strip. Does not execute, poll, or time anything — pure pushed state; `durationMs` is host-computed.
3206
+
3207
+ **Properties:**
3208
+ - `for: string = ''` — id of the target `lyra-flow-canvas`; empty resolves to the nearest ancestor
3209
+ - `decorations: FlowRunDecorations = {}` (attribute: false) — `Record<nodeOrEdgeId,
3210
+ FlowRunDecoration>`, pushed verbatim onto the resolved canvas's own `decorations` property
3211
+ - `hideSummary: boolean = false` (attribute `hide-summary`) — omits the "{done} of {total} steps
3212
+ complete" strip, keeping only the decoration push
3213
+ - `label: string = ''` — accessible name for the summary strip
3214
+
3215
+ **Events:** none dispatched directly.
3216
+
3217
+ **Slots:** default — extra host chrome appended to the strip (e.g. a cancel button or a usage
3218
+ badge).
3219
+
3220
+ **CSS parts:** `base`, `summary` (the "{done} of {total} steps complete" line), `count` (one per
3221
+ status present, text + tone dot, never color-only), `live-region` (step-transition announcement).
3222
+
3223
+ **Themeable custom properties:** shared tokens only.
3224
+
3225
+ **Optional peer deps:** none.
3226
+
3227
+ ```html
3228
+ <lyra-flow-canvas id="canvas" style="height:480px">
3229
+ <lyra-flow-run-overlay slot="top-start" for="canvas"></lyra-flow-run-overlay>
3230
+ </lyra-flow-canvas>
3231
+ <script>
3232
+ document.querySelector('lyra-flow-run-overlay').decorations = {
3233
+ a: { status: 'success', durationMs: 820 },
3234
+ b: { status: 'running', progress: 40 },
3235
+ };
3236
+ </script>
3237
+ ```
3238
+
3239
+ **Known gotchas:**
3240
+ - Purely a pushed-state conduit: it never starts, stops, or times a run itself — the host recomputes
3241
+ `decorations` (including `durationMs`) on whatever cadence its own execution engine ticks at.
3242
+ - `for` resolution matches `lyra-flow-minimap`/`lyra-flow-controls`.
3243
+
3244
+ ---
3245
+
3246
+ # Knowledge graph & RAG exploration
3247
+
3248
+ ## `lyra-graph-legend`
3249
+
3250
+ A node-type legend for a paired `lyra-graph`: one swatch + label + count row per node type, doubling
3251
+ as visibility filters. Never reads or writes a graph directly — the host forwards `types` in from
3252
+ `graph.nodeTypes` and `hiddenTypes` back out to `graph.hiddenTypes` on `lyra-visibility-change`, the
3253
+ same event-decoupled contract every sibling in this family follows.
3254
+
3255
+ **Properties:**
3256
+ - `types: LyraGraphLegendType[] = []` (attribute: false) — `{ id: string; label: string; color?:
3257
+ string; shape?: 'circle' | 'square' | 'diamond' }`, the exact `lyra-graph.nodeTypes` entry shape
3258
+ (declared locally, not imported, so this stays a zero-dependency component)
3259
+ - `counts?: Record<string, number>` (attribute: false) — optional per-type count shown alongside the
3260
+ label
3261
+ - `hiddenTypes: string[] = []` (attribute: false) — controlled; the host assigns this back from
3262
+ `lyra-visibility-change`
3263
+ - `interactive: boolean = true` (reflected) — renders each row as a toggle `<button>`; `false` renders
3264
+ plain, non-interactive rows
3265
+ - `label: string = ''` — accessible name for the `role="group"` wrapper
3266
+
3267
+ **Events:** `lyra-visibility-change` (`detail: { hiddenTypes }`, the complete updated array, fired
3268
+ after each toggle).
3269
+
3270
+ **Slots:** none.
3271
+
3272
+ **CSS parts:** `base`, `item` (a `<button>` when `interactive`, a plain `<div>` otherwise), `swatch`,
3273
+ `label`, `count`, `live-region` (the visually hidden filter-toggle announcement).
3274
+
3275
+ **Themeable custom properties:** no component-local tokens; reads `--lyra-graph-cat-1` through `-8`
3276
+ (the same computed-style fallback palette `lyra-graph`/`lyra-word-cloud` use) plus shared tokens.
3277
+
3278
+ **Optional peer deps:** none.
3279
+
3280
+ ```html
3281
+ <lyra-graph-legend id="legend"></lyra-graph-legend>
3282
+ <lyra-graph id="graph" style="height:480px"></lyra-graph>
3283
+ <script>
3284
+ const graph = document.getElementById('graph');
3285
+ const legend = document.getElementById('legend');
3286
+ legend.types = [{ id: 'person', label: 'Person', color: '#0969da' }, { id: 'org', label: 'Organization' }];
3287
+ legend.addEventListener('lyra-visibility-change', (e) => {
3288
+ legend.hiddenTypes = e.detail.hiddenTypes;
3289
+ graph.hiddenTypes = e.detail.hiddenTypes;
3290
+ });
3291
+ </script>
3292
+ ```
3293
+
3294
+ **Known gotchas:**
3295
+ - Ships no coupling to `lyra-graph`'s optional `d3-force`/`d3-drag`/`d3-zoom`/`d3-selection` peers —
3296
+ `types`/`counts`/`hiddenTypes` are plain data the host derives from a graph, never a live reference
3297
+ to one.
3298
+
3299
+ ---
3300
+
3301
+ ## `lyra-entity-card`
3302
+
3303
+ A dossier card for one knowledge-graph entity: type badge, description, key/value property rows,
3304
+ degree, community chip, plus a built-in "focus in graph" action. Never fetches or focuses a graph
3305
+ itself — `lyra-entity-activate` is a request a host routes into `lyra-graph`'s own
3306
+ `focusNode(id, options?)`.
3307
+
3308
+ **Properties:**
3309
+ - `entity: LyraEntity | null = null` (attribute: false) — `LyraEntity { id: string; label: string;
3310
+ type?: string; description?: string; properties?: Record<string, string | number>; degree?:
3311
+ number; communityId?: string }`; field names deliberately mirror `lyra-graph`'s `GraphNode`
3312
+ additions, so a graph node adapts into a `LyraEntity` with no mapping table; `null` renders the
3313
+ empty state
3314
+ - `types: NodeTypeStyle[] = []` (attribute: false) — the same `lyra-graph.nodeTypes`/
3315
+ `lyra-graph-legend.types` entry shape, resolving `entity.type` to a label/color/shape for the badge
3316
+ - `communityLabel: string = ''` (attribute `community-label`) — override text for the community chip
3317
+ - `showFocusButton: boolean = true` (attribute `show-focus-button`)
3318
+
3319
+ **Events:** `lyra-entity-activate` (`detail: { id }`, the built-in focus button was activated).
3320
+
3321
+ **Slots:** default (extra body content below the property rows, e.g. a `lyra-neighbor-list`),
3322
+ `actions` (extra header actions alongside the built-in focus button).
3323
+
3324
+ **CSS parts:** `base`, `header`, `type-badge`, `title` (`role="heading" aria-level="3"` by default),
3325
+ `description`, `properties`, `property` (one key/value row), `degree`, `community`, `actions`,
3326
+ `focus-button`, `empty` (shown when `entity` is `null`).
3327
+
3328
+ **Themeable custom properties:** shared tokens only; a data-driven `entity.type` color is applied as
3329
+ sanitized inline `--lyra-badge-*` overrides on the type badge only (the one "type color is
3330
+ data-driven by design" exception this library already grants graph nodes) — every other color comes
3331
+ from tokens.
3332
+
3333
+ **Optional peer deps:** none.
3334
+
3335
+ ```html
3336
+ <lyra-entity-card id="card"></lyra-entity-card>
3337
+ <script>
3338
+ document.getElementById('card').entity = {
3339
+ id: 'e1', label: 'Ada Lovelace', type: 'person',
3340
+ description: 'Mathematician', properties: { born: 1815 }, degree: 4,
3341
+ };
3342
+ document.getElementById('card').addEventListener('lyra-entity-activate', (e) => graph.focusNode(e.detail.id));
3343
+ </script>
3344
+ ```
3345
+
3346
+ **Known gotchas:**
3347
+ - The type badge's data-driven background uses a 10% (not this codebase's usual 16%) quiet-tint mix
3348
+ against `--lyra-color-surface` — the lower percentage is required to hold WCAG AA 4.5:1 text
3349
+ contrast for arbitrary, unvetted type colors.
3350
+
3351
+ ---
3352
+
3353
+ ## `lyra-entity-chip`
3354
+
3355
+ An inline `@entity` mention for agent prose: flow content, keyboard-focusable, with a hover/focus
3356
+ preview popover. The knowledge-graph sibling of `lyra-citation-badge`, reusing its interaction
3357
+ contract wholesale. Carries ids through events only — no entity data resolution, no navigation.
3358
+
3359
+ **Properties:**
3360
+ - `entityId: string = ''` (attribute `entity-id`)
3361
+ - `label: string = ''` — the chip's visible text
3362
+ - `type: string = ''` (reflected) — lets a host theme per type from CSS, e.g.
3363
+ `lyra-entity-chip[type='person'] { --lyra-entity-chip-color: ... }`
3364
+ - `typeLabel?: string` (attribute `type-label`) — optional spoken/visible type qualifier
3365
+
3366
+ **Events:** `lyra-entity-activate` (`detail: { id }`, click, or Enter while focused),
3367
+ `lyra-entity-open` (`detail: { id }`, dblclick, or Space while focused).
3368
+
3369
+ **Slots:** default — rich preview content (typically a compact `lyra-entity-card`), shown in a
3370
+ floating popover on hover/focus. No content means no popover and no hover affordance at all.
3371
+
3372
+ **CSS parts:** `base` (the clickable `<button>`), `label`, `popover`.
3373
+
3374
+ **Themeable custom properties:** `--lyra-entity-chip-color` (default `var(--lyra-color-brand)`,
3375
+ text/accent color), `--lyra-entity-chip-bg` (default `var(--lyra-color-brand-quiet)`).
3376
+
3377
+ **Optional peer deps:** none.
3378
+
3379
+ ```html
3380
+ <p>…first described by <lyra-entity-chip entity-id="e1" label="Ada Lovelace" type="person">
3381
+ <lyra-entity-card slot=""></lyra-entity-card>
3382
+ </lyra-entity-chip>.</p>
3383
+ ```
3384
+
3385
+ **Known gotchas:**
3386
+ - Reuses `lyra-citation-badge`'s exact "real preview content" detection (an assigned element with no
3387
+ other `slot`, or non-whitespace text) to decide whether a popover exists at all.
3388
+
3389
+ ---
3390
+
3391
+ ## `lyra-neighbor-list`
3392
+
3393
+ One entity's relationship rows: relation, direction, neighbor, with per-row navigate and
3394
+ expand-in-graph affordances. Never computes neighbors itself (the host derives rows from its own
3395
+ graph data) and never mutates a graph.
3396
+
3397
+ **Properties:**
3398
+ - `rows: LyraNeighborRow[] = []` (attribute: false) — `LyraNeighborRow { relation: string; direction:
3399
+ 'in' | 'out' | 'both'; node: LyraEntity }`
3400
+ - `groupByRelation: boolean = false` (attribute `group-by-relation`) — inserts a `group-header` row per
3401
+ distinct `relation`
3402
+ - `expandable: boolean = false` — renders a per-row expand-in-graph icon button
3403
+ - `virtualizeAt: number = 100` (attribute `virtualize-at`) — row count above which the list virtualizes
3404
+ - `label: string = ''`
3405
+
3406
+ **Events:** `lyra-entity-activate` (`detail: { id }`, a row's node button was activated),
3407
+ `lyra-node-expand` (`detail: { id }`, a row's expand button was activated — deliberately the same
3408
+ name and detail shape as `lyra-graph`'s own event, so one host handler serves both).
3409
+
3410
+ **Slots:** none.
3411
+
3412
+ **CSS parts:** `base` (`role="list"`), `group-header` (only when `groupByRelation`), `row`
3413
+ (`role="listitem"`), `direction` (`aria-hidden` glyph), `relation`, `node-label`, `node-meta`
3414
+ (secondary type/degree text, when present), `expand-button` (only when `expandable`), `empty`
3415
+ (shown when `rows` is empty).
3416
+
3417
+ **Themeable custom properties:** shared tokens only.
3418
+
3419
+ **Optional peer deps:** none.
3420
+
3421
+ ```html
3422
+ <lyra-neighbor-list expandable group-by-relation></lyra-neighbor-list>
3423
+ <script>
3424
+ document.querySelector('lyra-neighbor-list').rows = [
3425
+ { relation: 'works_for', direction: 'out', node: { id: 'e2', label: 'Analytical Engine Co.' } },
3426
+ ];
3427
+ </script>
3428
+ ```
3429
+
3430
+ **Known gotchas:**
3431
+ - `lyra-node-expand`'s detail shape is intentionally identical to `lyra-graph`'s own event of the
3432
+ same name, so a single listener wired to both handles "expand this node's neighborhood" uniformly.
3433
+
3434
+ ---
3435
+
3436
+ ## `lyra-path-strip`
3437
+
3438
+ A linear node → relation → node chain rendering "why A connects to B" (GraphRAG local-search
3439
+ reasoning paths) as a compact, horizontally scrollable strip. One-dimensional and presentational: no
3440
+ path finding, no branching, no per-element popovers.
3441
+
3442
+ **Properties:**
3443
+ - `path: LyraPathElement[] = []` (attribute: false) — a flat alternating sequence:
3444
+ `{ kind: 'node'; node: LyraEntity } | { kind: 'edge'; relation: string; directed?: boolean;
3445
+ reverse?: boolean }`
3446
+ - `label: string = ''`
3447
+
3448
+ **Events:** `lyra-entity-activate` (`detail: { id }`, a node element activated),
3449
+ `lyra-relation-activate` (`detail: { relation, sourceId?, targetId? }`, an edge element activated —
3450
+ source/target resolved from the adjacent node elements, `undefined` when the path is malformed at
3451
+ that position).
3452
+
3453
+ **Slots:** none.
3454
+
3455
+ **CSS parts:** `base` (hosts the delegated roving-tabindex keydown handler), `node` (a `<button>`),
3456
+ `relation` (a `<button>`), `arrow` (`aria-hidden`, logical — mirrors under RTL), `empty` (shown when
3457
+ `path` is empty).
3458
+
3459
+ **Themeable custom properties:** shared tokens only.
3460
+
3461
+ **Optional peer deps:** none.
3462
+
3463
+ ```html
3464
+ <lyra-path-strip></lyra-path-strip>
3465
+ <script>
3466
+ document.querySelector('lyra-path-strip').path = [
3467
+ { kind: 'node', node: { id: 'a', label: 'Ada Lovelace' } },
3468
+ { kind: 'edge', relation: 'wrote', directed: true },
3469
+ { kind: 'node', node: { id: 'b', label: 'Notes on the Analytical Engine' } },
3470
+ ];
3471
+ </script>
3472
+ ```
3473
+
3474
+ **Known gotchas:**
3475
+ - Purely presentational rendering of a caller-supplied path — it never computes shortest paths or
3476
+ fetches relationship data itself, and never branches (one linear chain per instance).
3477
+
3478
+ ---
3479
+
3480
+ ## `lyra-community-card`
3481
+
3482
+ A cluster/community summary card (GraphRAG community report): label, LLM summary excerpt, member
3483
+ count, member chips with overflow, and a drill-in action. Doesn't own community rendering on the
3484
+ graph or membership fetching — `lyra-drill` asks the host to load members/subgraph.
3485
+
3486
+ **Properties:**
3487
+ - `community: LyraCommunity | null = null` (attribute: false) — `LyraCommunity { id: string; label:
3488
+ string; summary?: string; memberCount?: number }`; `memberCount` is authoritative when it exceeds
3489
+ `members.length`; `null` renders the empty state
3490
+ - `members: LyraEntity[] = []` (attribute: false) — rendered as chips, up to `maxMembers`
3491
+ - `maxMembers: number = 8` (attribute `max-members`) — remaining members collapse into a "+N"
3492
+ overflow chip
3493
+ - `compact: boolean = false` (reflected) — omits the summary excerpt and member chips
3494
+
3495
+ **Events:** `lyra-drill` (`detail: { id }`, the drill button, header, or overflow chip — all three
3496
+ mean "show me this whole community"), `lyra-entity-activate` (`detail: { id }`, a member chip was
3497
+ activated).
3498
+
3499
+ **Slots:** `actions` — extra header actions alongside the built-in drill button.
3500
+
3501
+ **CSS parts:** `base`, `header`, `title` (`role="heading" aria-level="3"` wrapping a `<button>`),
3502
+ `member-count`, `summary` (omitted in `compact`), `members` (omitted in `compact`), `member`,
3503
+ `overflow` (the "+N" chip button), `drill-button`, `actions`, `empty` (shown when `community` is
3504
+ `null`).
3505
+
3506
+ **Themeable custom properties:** shared tokens only.
3507
+
3508
+ **Optional peer deps:** none.
3509
+
3510
+ ```html
3511
+ <lyra-community-card></lyra-community-card>
3512
+ <script>
3513
+ document.querySelector('lyra-community-card').community = { id: 'c1', label: 'Early computing pioneers', summary: 'A cluster of 19th-century mathematicians and engineers.', memberCount: 12 };
3514
+ </script>
3515
+ ```
3516
+
3517
+ **Known gotchas:**
3518
+ - `memberCount` (not `members.length`) is the authoritative displayed count whenever it's larger —
3519
+ useful when the host sends only a preview slice of members alongside the real total.
3520
+
3521
+ ---
3522
+
3523
+ ## `lyra-chunk-inspector`
3524
+
3525
+ A ranked retrieved-chunks list: relevance score bars with tier tones, expandable chunk text, and the
3526
+ deep-link event that lands a chunk in `lyra-document-viewer`. Never fetches, ranks, or dedupes; never
3527
+ opens documents itself.
3528
+
3529
+ **Properties:**
3530
+ - `chunks: LyraChunk[] = []` (attribute: false) — `LyraChunk { id: string; text: string; score:
3531
+ number; sourceId: string; title?: string; page?: string | number; anchor?: LyraChunkAnchor }`;
3532
+ `score` is 0–1, `title` falls back to a localized "untitled source", `anchor` (the same
3533
+ discriminated union `lyra-document-viewer.anchor` accepts — page/text-quote/fragment/line-range/
3534
+ cell-range/cfi/time-range/region/node-path) is carried through `lyra-chunk-open` verbatim
3535
+ - `thresholds: { high: number; medium: number } = { high: 0.75, medium: 0.5 }` (attribute: false) —
3536
+ score-bar tier cutoffs
3537
+ - `sort: 'score' | 'none' = 'score'`
3538
+ - `activeId: string = ''` (attribute `active-id`)
3539
+ - `virtualizeAt: number = 50` (attribute `virtualize-at`)
3540
+ - `compact: boolean = false` (reflected) — hides the text preview/toggle, title/score row only
3541
+ - `label: string = ''`
3542
+
3543
+ **Events:** `lyra-chunk-open` (`detail: { id, sourceId, anchor? }`, a chunk's title/open button was
3544
+ activated — the event a host routes into `lyra-document-viewer`, setting `src` from `sourceId` and
3545
+ `anchor` from the chunk's own), `lyra-expand` (`detail: { id, expanded }`, a chunk's text toggle was
3546
+ activated).
3547
+
3548
+ **Slots:** none.
3549
+
3550
+ **CSS parts:** `base` (`role="group"`), `chunk` (`role="listitem"`), `score` (visible percent text),
3551
+ `score-bar` (`aria-hidden` track), `score-fill` (tone-mapped fill), `open-button`, `title` (the
3552
+ `<span>` inside `open-button` carrying the visible title text), `text` (line-clamped unless
3553
+ expanded, omitted when `compact`), `toggle` ("Show more"/"Show less", omitted when `compact`),
3554
+ `empty` (shown when `chunks` is empty).
3555
+
3556
+ **Themeable custom properties:** shared tokens only.
3557
+
3558
+ **Optional peer deps:** none.
3559
+
3560
+ ```html
3561
+ <lyra-chunk-inspector></lyra-chunk-inspector>
3562
+ <script>
3563
+ const inspector = document.querySelector('lyra-chunk-inspector');
3564
+ inspector.chunks = [
3565
+ { id: 'c1', text: 'Revenue grew 12% year over year…', score: 0.91, sourceId: 'doc-1', title: 'Q3 report', page: 4 },
3566
+ ];
3567
+ inspector.addEventListener('lyra-chunk-open', (e) => documentViewer.openAt(e.detail.sourceId, e.detail.anchor));
3568
+ </script>
3569
+ ```
3570
+
3571
+ **Known gotchas:**
3572
+ - `title` and `open-button` are split into two separate parts (rather than one dual-part-name
3573
+ element) because an exact-match `[part="..."]` CSS attribute selector — as this component's own
3574
+ tests use — cannot match a multi-token `part` attribute value.
3575
+
3576
+ ---
3577
+
3578
+ ## `lyra-source-picker`
3579
+
3580
+ A checkbox tree/list scoping which sources ground the next answer: tri-state folders, select-all,
3581
+ type icons, search. **Not `FormAssociated`, deliberately**: this is a scoping panel, not a form
3582
+ control — the selection is immediate app state consumed by the next retrieval call, exactly the
3583
+ stance `lyra-tool-select-dialog` already takes.
3584
+
3585
+ **Properties:**
3586
+ - `sources: LyraSourceEntry[] = []` (attribute: false) — `LyraSourceEntry { id: string; label:
3587
+ string; mimeType?: string; name?: string; children?: LyraSourceEntry[] }`; flat (no `children`) or
3588
+ a tree — presence of `children` makes a row a group/folder with tri-state select
3589
+ - `selectedIds: string[] = []` (attribute: false) — controlled; the host assigns this back from
3590
+ `lyra-sources-change`
3591
+ - `showSelectAll: boolean = true` (attribute `show-select-all`)
3592
+ - `searchable: boolean = true`
3593
+ - `label: string = ''`
3594
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — overrides the tree's computed
3595
+ accessible name; wins over `label` and the localized default, and attribute-reflects from a
3596
+ host-level `aria-label` so plain markup gets ARIA-name forwarding
3597
+
3598
+ **Events:** `lyra-sources-change` (`detail: { selectedIds }`, the complete updated leaf-id array,
3599
+ fired after every toggle including select-all).
3600
+
3601
+ **Slots:** none.
3602
+
3603
+ **CSS parts:** `base`, `search` (the built-in filter `lyra-input`, only when `searchable`),
3604
+ `select-all` (only when `showSelectAll`), `summary` ("{selected} of {total} selected"), `tree`
3605
+ (`role="tree"`), `item` (`role="treeitem"`), `checkbox` (tri-state glyph), `icon` (the
3606
+ `lyra-file-icon` type badge), `label`, `empty` (`noData` when `sources` is empty, `noMatches` when a
3607
+ filter empties the tree).
3608
+
3609
+ **Themeable custom properties:** shared tokens only.
3610
+
3611
+ **Optional peer deps:** none.
3612
+
3613
+ ```html
3614
+ <lyra-source-picker></lyra-source-picker>
3615
+ <script>
3616
+ const picker = document.querySelector('lyra-source-picker');
3617
+ picker.sources = [
3618
+ { id: 'folder-1', label: 'Reports', children: [{ id: 'doc-1', label: 'Q3.pdf', mimeType: 'application/pdf' }] },
3619
+ ];
3620
+ picker.addEventListener('lyra-sources-change', (e) => (retrievalScope = e.detail.selectedIds));
3621
+ </script>
3622
+ ```
3623
+
3624
+ **Known gotchas:**
3625
+ - Deliberately not form-associated — `lyra-sources-change` is the only wiring; there's no
3626
+ `name`/`value`/`FormData` participation the way a genuine form control would have.
3627
+
3628
+ ---
3629
+
3630
+ ## `lyra-provenance-panel`
3631
+
3632
+ The grounding breakdown for one answer: a sectioned disclosure panel (Entities / Relationships /
3633
+ Communities / Text chunks) composing this family's own pieces. The chat ↔ graph ↔ document glue
3634
+ component. Pure projection + event conduit: no fetching, no graph/viewer imports, no persistence.
3635
+
3636
+ **Properties:**
3637
+ - `provenance: LyraProvenance | null = null` (attribute: false) — `LyraProvenance { entities?:
3638
+ LyraEntity[]; relationships?: { path: LyraPathElement[] }[]; communities?: LyraCommunity[]; chunks?:
3639
+ LyraChunk[] }`; each present array renders through the matching sibling component (`lyra-entity-
3640
+ chip` row, one `lyra-path-strip` per relationship, `lyra-community-card`, `lyra-chunk-inspector`);
3641
+ `null` or every section empty renders the overall empty state
3642
+ - `types: NodeTypeStyle[] = []` (attribute: false) — forwarded to the Entities section's chips
3643
+ - `thresholds: { high: number; medium: number } = { high: 0.75, medium: 0.5 }` (attribute: false) —
3644
+ forwarded to the Text chunks section's `lyra-chunk-inspector`
3645
+ - `label: string = ''`
3646
+
3647
+ **Events:** `lyra-toggle` (`detail: { section, expanded }`, a section header was toggled —
3648
+ `section` is `'entities' | 'relationships' | 'communities' | 'chunks'`).
3649
+
3650
+ **Slots:** none.
3651
+
3652
+ **CSS parts:** `base`, `section`, `header` (a section's disclosure `<button>`), `count` (a section's
3653
+ item-count badge), `body` (`hidden` while collapsed), `empty` (shown when every section is empty).
3654
+
3655
+ **Themeable custom properties:** shared tokens only.
3656
+
3657
+ **Optional peer deps:** none.
3658
+
3659
+ ```html
3660
+ <lyra-provenance-panel></lyra-provenance-panel>
3661
+ <script>
3662
+ document.querySelector('lyra-provenance-panel').provenance = {
3663
+ entities: [{ id: 'e1', label: 'Ada Lovelace', type: 'person' }],
3664
+ chunks: [{ id: 'c1', text: 'Revenue grew 12%…', score: 0.91, sourceId: 'doc-1' }],
3665
+ };
3666
+ </script>
3667
+ ```
3668
+
3669
+ **Known gotchas:**
3670
+ - Composes `lyra-entity-chip`, `lyra-path-strip`, `lyra-community-card`, and `lyra-chunk-inspector`
3671
+ directly rather than reimplementing their rendering — events from those inner components (e.g.
3672
+ `lyra-entity-activate`, `lyra-chunk-open`) still bubble/compose up through this panel's light DOM
3673
+ for the host to handle in one place.
3674
+
3675
+ ---
3676
+
3677
+ ## `lyra-mind-map`
3678
+
3679
+ A radial expandable topic tree (NotebookLM Mind Maps): a spatial overview of a topic hierarchy where
3680
+ activating a topic drills in or hands the topic to the chat. Hierarchy, not network — no cross-links,
3681
+ no force simulation, no communities, no edge labels (that's `lyra-graph`). Zero-dependency SVG; the
3682
+ radial layout is closed-form arithmetic, in its own `mind-map-layout.ts` module, mirroring
3683
+ `lyra-word-cloud`'s dependency-free precedent.
3684
+
3685
+ **Properties:**
3686
+ - `topics: LyraTopic[] = []` (attribute: false) — `LyraTopic { id: string; label: string; children?:
3687
+ LyraTopic[] }`; a single root sits at the center, multiple roots hang off an implicit center hub
3688
+ - `label: string = ''` — accessible name for the SVG group and the implicit hub's text
3689
+ - `expandDepth: number = 1` (attribute `expand-depth`) — initial expansion depth (root + first
3690
+ ring); expansion state afterward is component-managed per topic id and survives `topics`
3691
+ reassignment
3692
+
3693
+ **Events:** `lyra-topic-select` (`detail: { id }`, a *leaf* topic was activated),
3694
+ `lyra-topic-toggle` (`detail: { id, expanded }`, a parent topic was activated, or auto-expanded by
3695
+ keyboard descent).
3696
+
3697
+ **Slots:** none.
3698
+
3699
+ **CSS parts:** `base`, `svg` (the single-tab-stop focus target), `node`, `node-label`, `link`
3700
+ (parent-child connector), `focus-ring` (keyboard focus ring), `live-region` (visually hidden
3701
+ announcement region), `empty` (shown when `topics` is empty).
2703
3702
 
2704
- **Themeable custom properties:** `--lyra-tree-depth` (internal, set inline per row for
2705
- indentation), plus the shared tokens listed above.
3703
+ **Themeable custom properties:** `--lyra-mind-map-ring-gap` (default `6rem`, radius step per depth
3704
+ ring).
2706
3705
 
2707
3706
  **Optional peer deps:** none.
2708
3707
 
2709
3708
  ```html
2710
- <lyra-tree></lyra-tree>
3709
+ <lyra-mind-map style="height:480px" expand-depth="2"></lyra-mind-map>
2711
3710
  <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
- },
3711
+ document.querySelector('lyra-mind-map').topics = [
3712
+ { id: 'root', label: 'Computing history', children: [
3713
+ { id: 'people', label: 'People', children: [{ id: 'ada', label: 'Ada Lovelace' }] },
3714
+ { id: 'machines', label: 'Machines' },
3715
+ ] },
2721
3716
  ];
2722
3717
  </script>
2723
3718
  ```
2724
3719
 
2725
3720
  **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.
3721
+ - A user's explicit expand/collapse only ever overrides the `depth < expandDepth` default in the
3722
+ direction chosen reassigning `topics` (even with the same ids) never silently discards that
3723
+ override.
3724
+ - Node-position transitions use `--lyra-transition-base`, which already collapses to near-zero under
3725
+ `prefers-reduced-motion: reduce` globally, so expansion snaps rather than tweening for a
3726
+ reduced-motion user with no extra branching in this component.
2740
3727
 
2741
3728
  ---
2742
3729
 
@@ -2759,6 +3746,12 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2759
3746
  noTooltip?: boolean; axis?: 'y'|'y2'; pointColors?: string[]; pointRadius?: number; type?:
2760
3747
  'line'|'bar' }`
2761
3748
  - `legend: boolean = false`
3749
+ - `legendPosition: LyraChartLegendPosition = 'top'` (attribute `legend-position`) — places the
3750
+ legend at `top`, `right`, `bottom`, or `left`; `auto` chooses right above 480px and bottom below
3751
+ that allocation width
3752
+ - `valueFormatter?: LyraChartValueFormatter` (attribute: false) — formats numeric tick, tooltip,
3753
+ and legend values; the callback receives the value and `'tick'`, `'tooltip'`, or `'legend'`
3754
+ context
2762
3755
  - `area: boolean = false`
2763
3756
  - `zoom: boolean = false`
2764
3757
  - `height: string = '280px'`
@@ -2780,6 +3773,9 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2780
3773
  localized data/trend summary
2781
3774
  - `showDataTable: boolean = false` (attribute `show-data-table`) — makes the always-available
2782
3775
  accessible data table visible rather than screen-reader-only
3776
+ - `chartArea: LyraChartArea | undefined` (readonly) — current Chart.js chart-area geometry in
3777
+ canvas-local coordinates (`top`, `left`, `right`, `bottom`, `width`, `height`), when a chart is
3778
+ drawn
2783
3779
 
2784
3780
  **Methods:** `resetZoom()` (reset any active zoom/pan to the original view), `refreshTheme()`
2785
3781
  (forces a redraw so the `--lyra-chart-*` tokens below are re-read from the current computed style —
@@ -2791,9 +3787,11 @@ the escape hatch for a consumer's own theme-toggle handler to call when it flips
2791
3787
  a data point/segment, for any chart type, not just bar; `detail: { datasetIndex: number, index:
2792
3788
  number, label: string | undefined, value: unknown }`)
2793
3789
 
2794
- **Slots:** `data-table` — an optional consumer-provided accessible table alternative.
3790
+ **Slots:** `data-table` — an optional consumer-provided accessible table alternative; `center` —
3791
+ optional overlay content positioned at the chart area's center, useful for doughnut and pie totals.
2795
3792
 
2796
- **CSS parts:** `base`, `canvas`, `reset-zoom-button`, `description`, `data-table`
3793
+ **CSS parts:** `base`, `canvas`, `reset-zoom-button`, `description`, `data-table`, `center` (the
3794
+ chart-area-centered wrapper for the `center` slot)
2797
3795
 
2798
3796
  **Themeable custom properties:** `--lyra-chart-height` (set programmatically on the host from the
2799
3797
  `height` property — must be read from the host, not a shadow-tree descendant, since custom
@@ -2908,6 +3906,10 @@ passthrough). Not a subclass of `LyraChart`.
2908
3906
  - `pointText?: (label: string, value: number, datasetIndex: number) => string` (attribute: false) —
2909
3907
  overrides the per-bar/per-point `<title>`/`aria-label` tooltip text (mirrors `lyra-heatmap`'s
2910
3908
  `cellText`). Falls back to the built-in raw-value template when unset.
3909
+ - `legendText?: (label: string, datasetIndex: number) => string` (attribute: false) — appends
3910
+ formatter-supplied text (e.g. a value or percentage share) after each series' label in the
3911
+ built-in legend row, mirroring `pointText`/`tickFormat`'s opt-in-hook convention. Falls back to
3912
+ the label alone when unset; no-op while `legend` is `false`.
2911
3913
  - `roundedBars: boolean = false` (attribute `rounded-bars`, bar type only) — draws each bar as a
2912
3914
  rounded-top-corner shape instead of a square-cornered `<rect>`.
2913
3915
  - `skipZero: boolean = false` (attribute `skip-zero`, bar type only) — omits a bar entirely (no
@@ -2950,8 +3952,9 @@ fresh, small SVG render is cheaper and more correct than a lossy cache.
2950
3952
 
2951
3953
  **CSS parts:** `base`, `grid-line`, `axis-label`, `axis-title`, `bar` (each bar rect; carries
2952
3954
  `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).
3955
+ `legend-item`, `legend-swatch`, `legend-text` (extra per-item text after the series label,
3956
+ rendered only when `legendText` is set), `live-region` (the current mark announcement for keyboard
3957
+ users), `data-list` (a visually hidden list of all plotted data points).
2955
3958
 
2956
3959
  **Themeable custom properties:** `--lyra-chart-height` (same host-level property as `lyra-chart`);
2957
3960
  `--lyra-chart-grid-color`, `--lyra-chart-tick-color`, `--lyra-chart-legend-color` — same token
@@ -3111,8 +4114,8 @@ independently of the base `chart-loader.ts`).
3111
4114
 
3112
4115
  ## `lyra-map`
3113
4116
 
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.
4117
+ A `maplibre-gl` wrapper with a declarative legend, a single choropleth GeoJSON fill layer, markers,
4118
+ and additive plain-GeoJSON `dataLayers`, plus a raw `map` escape hatch for anything unexposed.
3116
4119
 
3117
4120
  **Properties:**
3118
4121
  - `center: [number, number] = [0, 0]`
@@ -3137,6 +4140,17 @@ raw `map` escape hatch for anything unexposed.
3137
4140
  escaped) when the content is plain text. A marker whose `color` changes for a persisting `id`
3138
4141
  can't be recolored in place (no `Marker.setColor()`) and is torn down/reconstructed instead — see
3139
4142
  gotchas.
4143
+ - `dataLayers: GeoJsonDataLayer[] = []` (attribute: false) — `GeoJsonDataLayer { sourceId: string;
4144
+ geojson: GeoJSON.Feature | GeoJSON.FeatureCollection; tone?: 'accent' | 'success' | 'warning' |
4145
+ 'danger' | 'neutral' }`. Each entry adds one GeoJSON source plus three layers
4146
+ (`${sourceId}-fill`/`${sourceId}-line`/`${sourceId}-circle`, filtered by geometry type so a mixed
4147
+ `FeatureCollection` renders correctly across all three), colored from the matching `--lyra-color-*`
4148
+ token (`tone` defaults to `'accent'` → `--lyra-color-brand`). Independent of `choropleth` — no
4149
+ `field`/`stops` color-interpolation, just the geometry rendered in a flat tone; use `choropleth`
4150
+ instead when you need a data-driven color ramp. Reconciled by `sourceId` the same way `choropleth`
4151
+ is: an entry whose `sourceId` persists across a `dataLayers` reassignment gets its GeoJSON updated
4152
+ in place (`setData()`), one that's dropped has its source/layers removed, and a genuinely new
4153
+ `sourceId` gets a new source/layers — nothing leaks on removal, style change, or disconnect.
3140
4154
  - `label: string = ''` — accessible name for the map region, applied as `[part="base"]`'s
3141
4155
  `aria-label`. A plain `aria-label` attribute on the host itself is honored as a fallback when
3142
4156
  `label` is left unset, matching `lyra-slider`/`lyra-checkbox`/`lyra-switch`; with neither set, it
@@ -3181,9 +4195,9 @@ exists and was hit)
3181
4195
  `removeSource` on whatever was previously applied before adding the new one (or nothing, if
3182
4196
  cleared).
3183
4197
  - `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.
4198
+ already calling `setCenter`/`setZoom`) — the choropleth and `dataLayers` are both automatically
4199
+ re-applied once the new style's own `'style.load'` fires, since a style change wipes every
4200
+ layer/source maplibre-gl knows about.
3187
4201
  - Point markers now have a declarative API (`markers`, above) with popup support — the `.map` escape
3188
4202
  hatch and manual `new maplibregl.Marker()` are no longer the only way to place pins.
3189
4203
  - a marker whose `color` changes for a persisting `id` is torn down and reconstructed (maplibre-gl's
@@ -3704,6 +4718,9 @@ wrapper at all, so existing text-only tabs are unaffected.
3704
4718
  - `active: string = ''` (reflected) — the active tab's `slot`/id; falls back to the first enabled
3705
4719
  tab whenever the current value doesn't resolve to one (including on every children/attribute
3706
4720
  change, tracked via a `MutationObserver`)
4721
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — accessible name applied to the
4722
+ `role="tablist"` strip; attribute-reflects from a host-level `aria-label`. Unset, the tablist
4723
+ renders without an `aria-label` (there is no localized default name).
3707
4724
 
3708
4725
  **Events:** `lyra-tabs-change` (`detail: { tabId: string }`) — fired when the active tab changes via
3709
4726
  click or keyboard. Not fired when `active` self-corrects to a valid tab (initial default, or a tab
@@ -3766,6 +4783,9 @@ convention).
3766
4783
  - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — `'horizontal'` (the default)
3767
4784
  lays steps out in a row (Left/Right, RTL-aware, navigate); `'vertical'` stacks them (Up/Down
3768
4785
  navigate instead, no RTL swap needed).
4786
+ - `accessibleLabel: string | null = null` (attribute `aria-label`) — accessible name applied to the
4787
+ `role="tablist"` step strip; attribute-reflects from a host-level `aria-label`. Unset, the
4788
+ tablist renders without an `aria-label` (there is no localized default name).
3769
4789
 
3770
4790
  **Events:** `lyra-step-select` (`detail: { index, id }`) — fired on click, or Enter/Space while
3771
4791
  focused, on a non-`disabled` step. Cancelable, though this component takes no default action of its
@@ -4086,22 +5106,32 @@ stack overflow on cyclic `data`.
4086
5106
  - `search: string = ''` — case-insensitive substring match against keys/values; matches are
4087
5107
  highlighted and their ancestors auto-expanded
4088
5108
 
5109
+ **Methods:** `runSearch(query)` sets the declarative `search` property and awaits the recompute,
5110
+ resolving the match count — named distinctly from `search` because a class member can't share a name
5111
+ with a reactive property. `searchNext()`/`searchPrevious()` advance/step back a match cursor
5112
+ (wrapping) and scroll the active match into view, resolving `false` when there are no matches.
5113
+ `clearSearch()` resets `search` to `''`, clearing all matches and the cursor.
5114
+
4089
5115
  **Events:** `lyra-copy` (`detail: { text: string }`) — fired by the top-level copy button or a
4090
5116
  per-node one. Fires even when `navigator.clipboard` is unavailable or the write silently failed
4091
5117
  (a rejected `writeText()` is swallowed), so a consumer can still observe copy *intent* — the event
4092
5118
  is not a confirmation that the OS clipboard was actually reached. Copying a circular `data` value
4093
5119
  serializes safely, substituting the same `Circular reference` marker the tree view renders, instead
4094
- of throwing.
5120
+ of throwing. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — fired whenever the
5121
+ search query, match count, or active-match cursor changes, from `runSearch()`/`searchNext()`/
5122
+ `searchPrevious()`/`clearSearch()`, or a direct `search`/`data` property write.
4095
5123
 
4096
5124
  **Slots:** none — the tree is rendered entirely from `data`.
4097
5125
 
4098
5126
  **CSS parts:** `base` (root scroll container, respects `max-height`), `toolbar` (wrapper around the
4099
5127
  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`),
5128
+ tree), `key` (an object property key or array index label, `data-match` while it matches `search`,
5129
+ `data-active` while it is the current `searchNext()`/`searchPrevious()` cursor position),
4101
5130
  `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),
5131
+ `string`/`number`/`boolean`/`null`/`undefined`/`circular` for per-type coloring, `data-match`
5132
+ while it matches `search`, and `data-active` while it is the current cursor position), `bracket` (a
5133
+ `{`, `}`, `[`, or `]` delimiter), `toggle` (a container node's expand/collapse button; hidden but
5134
+ present for row alignment on leaf/empty nodes),
4105
5135
  `copy-button` (a copy-to-clipboard button — the top-level one in `toolbar` (aria-label "Copy JSON to
4106
5136
  clipboard") or a per-node one (aria-label `Copy ${key/type}`, e.g. "Copy age"); only rendered when
4107
5137
  `copyable`)
@@ -4246,6 +5276,15 @@ instance on a page shares one load. `heading`/`code`/`blockquote`/`table`/`link`
4246
5276
  rendered through a `marked` renderer override that injects `part="..."` attributes directly into the
4247
5277
  produced HTML in a single pass (no second DOM walk after insertion).
4248
5278
 
5279
+ Fenced code blocks are also syntax-highlighted via the same optional `shiki` peer `<lyra-code-block>`
5280
+ uses, gated by `highlightCode` (default `true`). This is a pure upgrade, not a separate opt-in: it's
5281
+ already transparently gated by whether `shiki` is installed at all, so an app that never installs the
5282
+ peer sees byte-identical output to before this property existed. The very first render of any content
5283
+ is always plain text/code (identical to today's output); highlighting arrives as an asynchronous
5284
+ upgrade one render later once shiki resolves and the block's language is tokenized. No highlighting
5285
+ is attempted while `streaming` is `true` — it applies once a stream settles, adding no per-chunk cost
5286
+ while content is still arriving.
5287
+
4249
5288
  **Properties:**
4250
5289
  - `content: string = ''` — the Markdown source to render
4251
5290
  - `sanitize: boolean = true` — sanitize `marked`'s HTML output with DOMPurify before rendering
@@ -4280,6 +5319,27 @@ produced HTML in a single pass (no second DOM walk after insertion).
4280
5319
  - `streaming: boolean = false` (reflected) — marks the host `aria-busy="true"` while partial Markdown
4281
5320
  is still arriving and lets consumers target `lyra-markdown[streaming]`; busy state also remains
4282
5321
  true while parser dependencies are loading
5322
+ - `highlightCode: boolean = true` (attribute `highlight-code`) — syntax-highlights fenced code
5323
+ blocks via the optional `shiki` peer. `true` (the default) upgrades every fenced block once the
5324
+ peer is available; set `false` to keep plain output even when `shiki` is installed. No effect
5325
+ while `streaming` is `true`
5326
+ - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — same shape and purpose as
5327
+ `<lyra-code-block>`'s own `languages`: a fine-grained, explicit language-grammar bundle scoping
5328
+ shiki's build output to just those grammars instead of its full ~200-language bundle. Forwarded
5329
+ verbatim to `loadShikiHighlighterCore()`. Unset (the default) uses the default full-bundle loader
5330
+ - `languagesOnly: boolean = false` (attribute `languages-only`) — same purpose as
5331
+ `<lyra-code-block>`'s own `languagesOnly`: skips the default full-bundle loader entirely, so a
5332
+ fenced block whose language isn't in `languages` falls back to plain unhighlighted text rather
5333
+ than reaching for the full bundle. No effect unless `languages` is also set
5334
+ - `headingAnchors: boolean = false` (attribute `heading-anchors`) — stamps a computed
5335
+ GitHub-slugger-style slug as `id` on every rendered heading.
5336
+ - `math: boolean = false` — renders `$inline$` and `$$block$$` TeX via the optional `katex` peer,
5337
+ lazy-loaded the same way as `marked`/`dompurify`/`shiki`.
5338
+ - `anchorKinds: readonly ('fragment' | 'text-quote')[]` (readonly) — the anchor kinds this
5339
+ component resolves for the shared anchor-target contract.
5340
+
5341
+ **Methods:** `getHeadingTree()` returns the document-ordered heading outline (`{ level, text, slug
5342
+ }[]`) computed on every parse, regardless of `headingAnchors`.
4283
5343
 
4284
5344
  **Events:** `lyra-link-click` (`detail: { href: string, internal: true }`, fired — with the click
4285
5345
  prevented — when a rendered link's `href` starts with `internal-link-prefix`; ordinary external
@@ -4304,7 +5364,10 @@ Menlo, Consolas, monospace` — the code/code-block font; component-specific sin
4304
5364
  **Optional peer deps:** `marked`, `dompurify` (both lazy-loaded via `markdown-loader.ts`'s
4305
5365
  `loadMarkdownDeps()`, mirroring `chart-loader.ts`'s two-independent-optional-peers shape). Each half
4306
5366
  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.
5367
+ `sanitize="false"` (so `dompurify` is never needed) is a valid, supported combination. Also `shiki`,
5368
+ the same optional peer `<lyra-code-block>` uses, for `highlightCode`'s fenced-block syntax
5369
+ highlighting — independent of the `marked`/`dompurify` pair, and its absence never blocks rendering
5370
+ (fenced blocks simply stay unhighlighted).
4308
5371
 
4309
5372
  ```html
4310
5373
  <lyra-markdown
@@ -4381,6 +5444,10 @@ conversation-surface level).
4381
5444
  rendered) — mirrors `lyra-widget`'s identical `collapsible`/`collapsed` pair
4382
5445
  - `attachmentsPosition: 'before'|'after' = 'after'` (attribute `attachments-position`) — places the
4383
5446
  `attachments` slot before or after the message body; both the visual and reading order follow it
5447
+ - `actionsOutsideBubble: boolean = false` (attribute `actions-outside-bubble`, reflected) — renders
5448
+ the `actions` slot's content as a sibling immediately after `[part="bubble"]` instead of nested
5449
+ inside `[part="footer"]`'s own padding/background box, for a consumer whose action row (e.g. a
5450
+ hover-reveal copy button) must sit visually outside the bubble's chrome
4384
5451
 
4385
5452
  **Events:** `lyra-retry` (no detail payload; fired by the built-in retry button, only rendered when
4386
5453
  `status="failed"`), `lyra-collapse-toggle` (`detail: boolean`, the new `collapsed` state — fired when
@@ -4396,6 +5463,8 @@ attachment chips, rendered below the message body)
4396
5463
  `attachments`, `footer` (hidden entirely when nothing is in it), `status-indicator` (a small
4397
5464
  decorative `aria-hidden` dot, absent while `status="sent"`), `status-text` (the visible text twin of
4398
5465
  `status-indicator`), `timestamp`, `retry-button` (only rendered when `status="failed"`), `actions`
5466
+ (rendered inside the footer by default; a sibling immediately after `bubble` when
5467
+ `actionsOutsideBubble` is set)
4399
5468
 
4400
5469
  **Themeable custom properties:** `--lyra-chat-message-max-width` (default `80%` — the bubble's max
4401
5470
  inline size; component-specific, no shared width token exists), plus shared tokens
@@ -5301,6 +6370,15 @@ invention (no Web Awesome equivalent).
5301
6370
  - `rowHeight: string = 'auto'` (attribute `row-height`) — `'auto'` measures each row's real height via
5302
6371
  `ResizeObserver`; a numeric string (e.g. `"56"`) fixes every row to that many pixels. Anything else
5303
6372
  (non-numeric, zero, negative, non-finite) silently falls back to `'auto'` rather than throwing.
6373
+ - `itemRole: 'listitem' | 'row' = 'listitem'` (attribute `item-role`) — `'listitem'` (default)
6374
+ preserves the plain `role="list"`/`role="listitem"` mapping with `aria-setsize`/`aria-posinset`.
6375
+ `'row'` additionally maps `[part="base"]` to `role="rowgroup"`, `[part="spacer"]` to
6376
+ `role="presentation"`, and each row to `role="row"` with `aria-rowindex` instead — for a consumer
6377
+ composing its own `role="table"` wrapper and header row around this component (see
6378
+ `lyra-dataset-viewer`).
6379
+ - `rowIndexOffset: number = 0` (attribute `row-index-offset`) — added to a row's 1-based index to
6380
+ compute `aria-rowindex` in `item-role="row"` mode (e.g. `1` when a consumer renders its own header
6381
+ row occupying `aria-rowindex="1"` outside this component). No effect in `'listitem'` mode.
5304
6382
  - `overscan: number = 6` — extra rows rendered beyond the visible viewport on each side; finite
5305
6383
  values are floored and clamped to 0–100, while non-finite values use the default 6, so an invalid
5306
6384
  runtime value cannot disable windowing and render the entire collection.
@@ -5320,6 +6398,12 @@ The package root also exports `groupByRecency(items, options?)`, a DOM-free help
5320
6398
  non-empty Today/Yesterday/Previous 7 Days/Older buckets, preserves input order within each bucket,
5321
6399
  and accepts a timestamp extractor, reference date, and label overrides.
5322
6400
 
6401
+ **Methods:** `scrollToIndex(index, options?)` — the programmatic counterpart to `active-id`'s
6402
+ automatic scroll-into-view, for a host that needs to scroll to a specific row without changing which
6403
+ row is "active." `options.align` is `'start'`, `'end'`, or `'auto'` (default — no scroll at all when
6404
+ already fully visible); `options.behavior` (default `'smooth'`) is forced to `'auto'` under
6405
+ `prefers-reduced-motion: reduce`. `index` is clamped to `0…items.length-1`.
6406
+
5323
6407
  **Events:** `lyra-load-more` (no detail — fired once per approach to the bottom of the list while
5324
6408
  `has-more` is true and `loading` is false; does not refire on every scroll tick while still near the
5325
6409
  bottom — scrolling back away from the bottom and returning, or `items` growing enough to move the
@@ -5328,10 +6412,12 @@ current visible, non-overscanned item index range — fired only when it actuall
5328
6412
 
5329
6413
  **Slots:** none — all content comes from `renderItem`.
5330
6414
 
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)
6415
+ **CSS parts:** `base` (the scrollable container, `role="list"` — or `role="rowgroup"` in
6416
+ `item-role="row"` mode `tabindex="0"`), `spacer` (the full-content-height inner element
6417
+ establishing true scroll extent; `role="presentation"` in `item-role="row"` mode), `row` (one
6418
+ rendered row's absolutely-positioned wrapper, `role="listitem"` — or `role="row"` with
6419
+ `aria-rowindex` in `item-role="row"` mode), `group` (a `groups` entry's positioned `role="heading"`
6420
+ marker)
5335
6421
 
5336
6422
  **Themeable custom properties:** `--lyra-virtual-list-height` (default `24rem` — the host's bounded
5337
6423
  scroll extent; component-specific since a virtualized list is meaningless without a sized viewport),
@@ -6751,6 +7837,19 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6751
7837
  code scrolls internally past this height instead of growing the page
6752
7838
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6753
7839
  numbers for both highlighted output and the plain-text fallback
7840
+ - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
7841
+ line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
7842
+ with, and renders identically to, any `line-range` entries there.
7843
+ - `interactiveLines: boolean = false` (attribute `interactive-lines`) — turns the
7844
+ (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lyra-line-click`.
7845
+ Has no effect while `lineNumbers` is unset.
7846
+ - `highlights: LyraHighlight[] = []` (attribute: false) — host-supplied highlights to paint over the
7847
+ code (the shared anchor-target `LyraHighlight` contract from `document-viewer/anchors.ts`). Only
7848
+ `line-range` anchors are meaningful here — every other `LyraAnchor` kind is ignored.
7849
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
7850
+ entry, if any, currently treated as active (`data-active` on its lines).
7851
+ - `anchorKinds: LyraAnchor['kind'][]` — readonly `['line-range']`, for the shared anchor-target
7852
+ contract.
6754
7853
  - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — a map of language id to an
6755
7854
  already-imported shiki grammar module (e.g. `{ bash: bashGrammar }` from a module-scope
6756
7855
  `import bash from 'shiki/langs/bash.mjs'`). When `language` matches a key here, highlighting is
@@ -6762,15 +7861,26 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6762
7861
  - `languagesOnly: boolean = false` (attribute `languages-only`) — skips the default shiki loader;
6763
7862
  use when every requested language is supplied through `languages`
6764
7863
 
7864
+ **Methods:** `scrollToAnchor(target)` — resolves a `line-range` anchor (or a `highlights` id string
7865
+ resolving to one) by scrolling its start line into view within `[part="body"]`; resolves `false`
7866
+ when the anchor isn't a `line-range`, the id isn't found, or the start line is out of bounds.
7867
+
6765
7868
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6766
7869
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6767
7870
  `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`)
7871
+ button is activated, same event name/shape convention as `<lyra-thinking-panel>`'s own `lyra-toggle`),
7872
+ `lyra-line-click` (`detail: { line: number }` — a gutter line number was activated while
7873
+ `interactiveLines` is set), `lyra-highlight-activate` (`detail: { id: string }` — declared for
7874
+ parity with this library's other anchor-target viewers; not currently emitted by this component),
7875
+ `lyra-text-select` (`detail: { text, anchor, rects }` — a text selection inside the code body ended;
7876
+ `anchor` is a `line-range` anchor covering the selected lines)
6769
7877
 
6770
7878
  **Slots:** none.
6771
7879
 
6772
7880
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6773
- `code`
7881
+ `code`, `line-highlight` (a line marked by `highlightLines` or a `line-range` entry in `highlights`),
7882
+ `line-button` (a gutter line-number button, only rendered while `interactiveLines` and `lineNumbers`
7883
+ are both set)
6774
7884
 
6775
7885
  **Themeable custom properties:** `--lyra-code-block-max-height` (default `none` — the consumer-tunable
6776
7886
  scroll cap; only takes effect once `max-height` is set), `--lyra-code-block-font` (default
@@ -6868,19 +7978,40 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
6868
7978
  code scrolls internally past this height instead of growing the page.
6869
7979
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6870
7980
  numbers for highlighted and plain output.
7981
+ - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
7982
+ line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
7983
+ with, and renders identically to, any `line-range` entries there.
7984
+ - `interactiveLines: boolean = false` (attribute `interactive-lines`) — turns the
7985
+ (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lyra-line-click`.
7986
+ Has no effect while `lineNumbers` is unset.
7987
+ - `highlights: LyraHighlight[] = []` (attribute: false) — host-supplied highlights to paint over the
7988
+ code. Only `line-range` anchors are meaningful here — every other `LyraAnchor` kind is ignored.
7989
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
7990
+ entry, if any, currently treated as active (`data-active` on its lines).
7991
+ - `anchorKinds: LyraAnchor['kind'][]` — readonly `['line-range']`, for the shared anchor-target
7992
+ contract, identical to `<lyra-code-block>`.
6871
7993
  - `languages: Record<string, ShikiLanguageInput> = {}` (attribute: false) — grammar definitions this
6872
7994
  instance can highlight, e.g. `{ json: jsonGrammar }` (import from `shiki/langs/<name>.mjs`). Empty
6873
7995
  (the default) never highlights at all — every `language` renders the plain-text fallback.
6874
7996
 
7997
+ **Methods:** `scrollToAnchor(target)` — resolves a `line-range` anchor (or a `highlights` id string
7998
+ resolving to one) by scrolling its start line into view within `[part="body"]`; resolves `false`
7999
+ when the anchor isn't a `line-range`, the id isn't found, or the start line is out of bounds.
8000
+ Identical behavior to `<lyra-code-block>`'s own method.
8001
+
6875
8002
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6876
8003
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6877
8004
  `lyra-toggle` (`detail: { collapsed: boolean }` — fired when the built-in collapse/expand header
6878
- button is activated).
8005
+ button is activated), `lyra-line-click` (`detail: { line: number }` — a gutter line number was
8006
+ activated while `interactiveLines` is set), `lyra-highlight-activate` (`detail: { id: string }` —
8007
+ declared for parity with this library's other anchor-target viewers; not currently emitted by this
8008
+ component), `lyra-text-select` (`detail: { text, anchor, rects }` — a text selection inside the code
8009
+ body ended; `anchor` is a `line-range` anchor covering the selected lines).
6879
8010
 
6880
8011
  **Slots:** none.
6881
8012
 
6882
8013
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6883
- `code` — identical set to `<lyra-code-block>`.
8014
+ `code`, `line-highlight`, `line-button` — identical set to `<lyra-code-block>`.
6884
8015
 
6885
8016
  **Themeable custom properties:** identical to `<lyra-code-block>` — `--lyra-code-block-max-height`,
6886
8017
  `--lyra-code-block-font`, plus the same shared tokens.
@@ -6927,6 +8058,15 @@ First-party invention (no Web Awesome equivalent).
6927
8058
  all-removals diff of `oldText`.
6928
8059
  - `copyable: boolean = false` — shows a copy-to-clipboard button for the full unified-diff text.
6929
8060
  `false` (the default) renders no button.
8061
+ - `layout: 'unified' | 'split' = 'unified'` (reflected) — `'unified'` (the default) renders today's
8062
+ single interleaved `<pre>`; `'split'` renders two side-by-side `[part="side"]` columns derived from
8063
+ the same diff alignment.
8064
+ - `language: string = ''` — a shiki-recognized language id. Highlighting activates only when this
8065
+ has a matching entry in `languages` — there is deliberately no default full-table
8066
+ `lyra-code-block`-style fallback, so this component never reaches shiki's ~200-language
8067
+ dynamic-import table.
8068
+ - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — grammar definitions this
8069
+ instance can highlight, same shape as `lyra-code-block-core`'s own `languages`.
6930
8070
 
6931
8071
  **Events:** `lyra-copy` (`detail: { text: string }` — the full unified-diff text, fired on
6932
8072
  copy-button activation regardless of whether the clipboard write actually succeeded).
@@ -6934,15 +8074,19 @@ copy-button activation regardless of whether the clipboard write actually succee
6934
8074
  **Slots:** none.
6935
8075
 
6936
8076
  **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`).
8077
+ `data-type="equal"|"add"|"remove"|"empty"` `"empty"` is an unbalanced-replace placeholder cell in
8078
+ `layout="split"` and never carries a `+`/`-` prefix), `copy-button` (the copy affordance, only
8079
+ rendered while `copyable`), `side` (one column in `layout="split"`, `data-side="old"|"new"`).
6939
8080
 
6940
8081
  **Themeable custom properties:** `--lyra-diff-view-font` (default `var(--lyra-font-mono)`), plus
6941
8082
  shared tokens `--lyra-color-border`/`-surface`/`-success`/`-success-quiet`/`-danger`/
6942
8083
  `-danger-quiet`/`-text`, `--lyra-radius`, `--lyra-space-xs`/`-s`, `--lyra-font-size-sm`,
6943
8084
  `--lyra-line-height-snug`, `--lyra-focus-ring-*`.
6944
8085
 
6945
- **Optional peer deps:** none.
8086
+ **Optional peer deps:** `shiki` (the same fine-grained `shiki/core`/`shiki/engine/oniguruma`/
8087
+ `shiki/wasm` subset `lyra-code-block-core` uses, never `shiki`'s full ~200-language main entry point)
8088
+ — only loaded once both `language` and a matching `languages` entry are set; unset/unmatched leaves
8089
+ the plain unhighlighted diff text untouched.
6946
8090
 
6947
8091
  ```html
6948
8092
  <lyra-diff-view copyable></lyra-diff-view>
@@ -6970,6 +8114,72 @@ consumer can compute or unit-test the same alignment without instantiating the e
6970
8114
 
6971
8115
  ---
6972
8116
 
8117
+ ## `lyra-stack-trace`
8118
+
8119
+ Parses common V8/JS-TS, Firefox/Safari, and Python stack traces into a leading message plus
8120
+ activatable frames, splitting chained/caused-by errors (`Caused by:`, `[cause]:`, Python's "direct
8121
+ cause"/"During handling" separators) into separate groups. Frames matching `internalPatterns` fold
8122
+ behind a count-labeled toggle. Falls back to verbatim raw text when nothing parses. First-party
8123
+ invention (no Web Awesome equivalent).
8124
+
8125
+ **Properties:**
8126
+ - `trace: string = ''` — the raw stack trace text to parse and render.
8127
+ - `collapseInternal: boolean = true` (attribute: `collapse-internal`) — folds runs of internal
8128
+ frames behind a toggle.
8129
+ - `internalPatterns: (string | RegExp)[] = DEFAULT_INTERNAL_PATTERNS` (attribute: false) —
8130
+ file-path substrings/`RegExp`s that mark a frame as internal.
8131
+ - `copyable: boolean = true` — shows a copy-to-clipboard button for the raw trace text.
8132
+ - `maxHeight: string = ''` (attribute: `max-height`) — caps the rendered block size and enables an
8133
+ internal scrollbar once content exceeds it (any valid CSS length). Empty string (the default)
8134
+ grows with content.
8135
+
8136
+ **Events:**
8137
+ - `lyra-frame-select` (`detail: { file?: string; line?: number; column?: number; raw: string }`) —
8138
+ a frame was activated. `column` is always undefined for Python frames, which carry no column
8139
+ information.
8140
+ - `lyra-copy` (`detail: { text: string }`) — the raw, unparsed trace text, fired on copy-button
8141
+ activation regardless of whether the clipboard write actually succeeded.
8142
+
8143
+ **Slots:** none.
8144
+
8145
+ **CSS parts:** `base` (the root wrapper; respects `max-height`), `message` (the leading error
8146
+ message text for a group), `group` (one chained-error group of frames), `frame` (a single frame
8147
+ button; carries `data-internal` for internal frames), `frame-function` (the frame's function
8148
+ name), `frame-location` (the frame's `file:line:col` text), `internal-toggle` (the collapse/expand
8149
+ toggle for a run of internal frames), `raw` (the verbatim fallback when zero structured frames
8150
+ parsed), `copy-button` (only rendered while `copyable`).
8151
+
8152
+ **Themeable custom properties:** `--lyra-stack-trace-max-height` (default `none`),
8153
+ `--lyra-stack-trace-font` (default `var(--lyra-font-mono)`), plus shared tokens
8154
+ `--lyra-color-border`/`-surface`/`-text`/`-text-quiet`/`-brand`, `--lyra-radius`,
8155
+ `--lyra-border-width-thin`, `--lyra-space-xs`/`-s`/`-2xs`, `--lyra-font-size-sm`/`-xs`,
8156
+ `--lyra-font-weight-bold`/`-semibold`, `--lyra-focus-ring-*`.
8157
+
8158
+ **Optional peer deps:** none.
8159
+
8160
+ ```html
8161
+ <lyra-stack-trace></lyra-stack-trace>
8162
+ <script type="module">
8163
+ const stackTrace = document.querySelector('lyra-stack-trace');
8164
+ stackTrace.trace = 'TypeError: boom\n at doThing (/app/src/util.js:10:5)';
8165
+ stackTrace.addEventListener('lyra-frame-select', (e) => console.log(e.detail.file, e.detail.line));
8166
+ </script>
8167
+ ```
8168
+
8169
+ The package root also exports the pure `parseStackTrace(trace: string, internalPatterns: (string |
8170
+ RegExp)[]): StackGroup[]` helper (plus `DEFAULT_INTERNAL_PATTERNS`, and the `StackFrame`/
8171
+ `StackGroup` types) — the same parsing function this component's own `willUpdate()` calls, exposed
8172
+ standalone so a consumer can parse or unit-test traces without instantiating the element at all.
8173
+
8174
+ **Known gotchas:**
8175
+ - an internal-frame run only collapses behind the `internal-toggle` when it is two or more
8176
+ consecutive internal frames; a single isolated internal frame renders as a normal `frame` button
8177
+ (there is nothing useful to fold).
8178
+ - when `trace` doesn't match any of the supported formats, `parseStackTrace()` returns `[]` and the
8179
+ component renders the text verbatim in a `raw` part instead of silently dropping content.
8180
+
8181
+ ---
8182
+
6973
8183
  ## `lyra-tool-approval-dialog`
6974
8184
 
6975
8185
  A human-in-the-loop gate: presents one proposed tool/function call (`toolName` + `args`) and blocks an
@@ -7619,8 +8829,9 @@ used" summary.
7619
8829
 
7620
8830
  **Properties:**
7621
8831
  - `segments: ContextMeterSegment[] = []` (attribute: false, JS-only) — `{ label: string; value:
7622
- number; tone?: 'brand' | 'success' | 'warning' | 'danger' | 'neutral' }[]`. `value` is an *absolute*
8832
+ number; tone?: 'brand' | 'success' | 'warning' | 'danger' | 'neutral'; color?: string }[]`. `value` is an *absolute*
7623
8833
  quantity measured against `total`, never a pre-computed percentage.
8834
+ `color`, when supplied, is a sanitized arbitrary CSS color that takes precedence over `tone`.
7624
8835
  - `total: number = 0` — the full capacity segments are measured against (e.g. a model's context
7625
8836
  window size).
7626
8837
  - `variant: 'ring' | 'bar' = 'bar'` (reflected)
@@ -7635,9 +8846,11 @@ A host `aria-label` overrides the generated meter summary and is preserved acros
7635
8846
  **Slots:** none.
7636
8847
 
7637
8848
  **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`
8849
+ capacity), `segment` (one occupied segment — carries `data-tone` and, for custom colors,
8850
+ `--lyra-context-meter-segment-color`), `label`
7639
8851
 
7640
- **Themeable custom properties:** no component-specific custom properties; consumes shared tokens
8852
+ **Themeable custom properties:** `--lyra-context-meter-segment-color` is set per segment when its
8853
+ `color` field is supplied; otherwise the component consumes shared tokens
7641
8854
  `--lyra-space-xs`, `--lyra-color-text-quiet`, `--lyra-font`, `--lyra-radius`, `--lyra-color-border`,
7642
8855
  `--lyra-color-surface` (the bar variant's inter-segment seam), `--lyra-color-brand`,
7643
8856
  `--lyra-color-success`, `--lyra-color-warning`, `--lyra-color-danger`, `--lyra-transition-base`.
@@ -7840,6 +9053,20 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7840
9053
  - `maxHeight: string = ''` (attribute `max-height`) — a CSS length (e.g. `"24rem"`); once set,
7841
9054
  `[part="body"]` scrolls internally past this height instead of growing the page — same contract as
7842
9055
  `lyra-json-viewer`'s identically-named prop.
9056
+ - `zoomable: boolean = false` (reflected) — wraps the rendered image (image format only) in an
9057
+ internal `<lyra-zoomable-frame>`. `false` (the default) preserves the exact pre-`zoomable` DOM — an
9058
+ inline thumbnail (e.g. in a chat stream) must not unexpectedly grow a focusable zoom-chrome
9059
+ viewport; an inspection surface opts in.
9060
+ - `highlights: LyraHighlight[] = []` (attribute: false) — display-only `region` highlights painted
9061
+ over the image-format preview; ignored for the `text`/`generic` formats.
9062
+ - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
9063
+ entry, if any, currently treated as active (`data-active` on its `region-highlight`).
9064
+ - `anchorKinds` is a readonly `['region']` (this viewer's supported `LyraAnchor.kind` values for the
9065
+ shared anchor-target contract).
9066
+
9067
+ **Methods:** `scrollToAnchor(target)` — scrolls a `region` highlight (by id, or a `LyraAnchor`
9068
+ matched back to its owning `LyraHighlight` by reference) into view; resolves `false` when nothing
9069
+ matches, the anchor isn't `region`, or the format isn't currently `image`.
7843
9070
 
7844
9071
  **Events:**
7845
9072
  - `lyra-download` — `detail: { src, filename }` — fired when the generic-download fallback's link is
@@ -7848,6 +9075,8 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7848
9075
  - `lyra-render-error` — `detail: { error }` — fired when this component's own `text/*`/
7849
9076
  `application/json` `fetch(src)` fails (network error or non-2xx response). Distinct from
7850
9077
  `status="error"`, which is entirely host-driven.
9078
+ - `lyra-highlight-activate` — `detail: { id }` — a region highlight was clicked or activated via
9079
+ Enter/Space (image format only).
7851
9080
 
7852
9081
  **Slots:** `unsupported` — escape hatch: when populated, its content renders *instead of* the generic
7853
9082
  download fallback for any `mime-type` this component doesn't natively support. Ignored while
@@ -7858,7 +9087,11 @@ download fallback for any `mime-type` this component doesn't natively support. I
7858
9087
  used both for `status="converting"` and this component's own in-flight text fetch), `error`
7859
9088
  (`role="alert"` — used both for `status="error"` and a failed text fetch), `download-link` (only
7860
9089
  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)
9090
+ above; excludes `data:` even though the other two sinks allow it), `highlight-layer` (wrapper around
9091
+ every rendered region highlight, image format only), `region-highlight` (one region highlight,
9092
+ `data-tone`, `data-active`; image format only), `frame-viewport`/`frame-content`/`frame-controls`/
9093
+ `frame-zoom-in`/`frame-zoom-out`/`frame-reset` (forwarded from the internal `<lyra-zoomable-frame>`
9094
+ while `zoomable`; image format only)
7862
9095
 
7863
9096
  **Themeable custom properties:** `--lyra-document-preview-max-height` (default `none`) — the
7864
9097
  consumer-tunable scroll cap on `[part="body"]`, set from `max-height`; `none` means the preview grows
@@ -7943,6 +9176,13 @@ type. First-party invention.
7943
9176
  - `src: string = ''` — source URL passed to the selected renderer or the fallback preview.
7944
9177
  - `registry?: DocumentRendererRegistry` (attribute: false) — optional per-instance registry override;
7945
9178
  the module-level registry is used when unset.
9179
+ - `alt: string = ''` — media alt text forwarded to the resolved renderer, for image-like renderers.
9180
+ - `anchor: LyraAnchor | string | null = null` (attribute: false) — declarative scroll-to-anchor
9181
+ target forwarded to the resolved renderer; a string is a highlight id in `highlights`.
9182
+ `hasChanged: () => true`, so re-assigning the same value (e.g. re-clicking the same citation
9183
+ badge) still re-fires.
9184
+ - `highlights: LyraHighlight[] = []` (attribute: false) — highlights forwarded to the resolved
9185
+ renderer.
7946
9186
 
7947
9187
  **Events:**
7948
9188
  - `lyra-close` — `detail: DocumentViewerCloseReason`, the nested dialog's dismissal reason. The
@@ -7994,13 +9234,33 @@ Mammoth preserves document structure such as headings, paragraphs, lists, tables
7994
9234
  not intended to reproduce pixel-exact Word page layout. There is no unsanitized rendering escape
7995
9235
  hatch: if `dompurify` is unavailable, rendering is blocked even when Mammoth converted successfully.
7996
9236
 
9237
+ Every rendered heading's slug (the same GitHub-slugger-style algorithm `<lyra-markdown>` uses) is
9238
+ stamped as its `id` and cached into `getHeadingTree()`'s document-ordered outline. Adopts
9239
+ `DocumentAnchorTarget`: `fragment` anchors resolve against that outline, `text-quote` anchors via
9240
+ the shared quote-scoping helpers; `highlights` re-resolve by quote after every render.
9241
+
7997
9242
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
7998
- the scrollable document body.
9243
+ the scrollable document body. `anchorKinds` is a readonly `['fragment', 'text-quote']` (this
9244
+ viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
9245
+
9246
+ **Methods:** `getHeadingTree()` returns the document-ordered outline as `DocxHeadingItem[]` (`{ id,
9247
+ label, level }`), cached on every successful load. `search(query)` resolves the match count via a
9248
+ case-insensitive substring search over the rendered content's text (empty/whitespace query behaves
9249
+ like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches
9250
+ (wrapping, resolving `false` when there are none); `clearSearch()` clears the query, matches, and
9251
+ painted marks.
7999
9252
 
8000
9253
  **Events:** `lyra-render-error` with `detail.error` when fetching, conversion, sanitization, or a
8001
- non-fatal Mammoth conversion message occurs.
9254
+ non-fatal Mammoth conversion message occurs. `lyra-search-change` (`detail: { query, matchCount,
9255
+ activeIndex }`) — from `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
9256
+ `lyra-highlight-activate` (`detail: { id }`) — a painted `text-quote` highlight was clicked.
9257
+ `lyra-text-select` (`detail: { text, anchor, rects }`) — fired on selection end inside the rendered
9258
+ content. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9259
+ `scrollToAnchor()` call.
8002
9260
 
8003
- **CSS parts:** `base`, `body`, `content`, `spinner`, and `error`.
9261
+ **CSS parts:** `base`, `body`, `content`, `spinner`, `error`, `highlight` (a painted `text-quote`
9262
+ highlight), `search-match` (a painted in-document search match), and `search-match-active` (the
9263
+ currently active search match, also carries `search-match`).
8004
9264
 
8005
9265
  **Optional peer dependencies:** install `mammoth` and `dompurify` with `pnpm add mammoth dompurify`.
8006
9266
  The component registers an eager `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
@@ -8025,13 +9285,17 @@ remain available without DOMPurify. Attachments are listed as filename and size
8025
9285
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
8026
9286
  `documentPreviewResourceTooLarge` message instead of the message.
8027
9287
 
8028
- **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings.
9288
+ **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `foldQuotes:
9289
+ boolean = false` (attribute `fold-quotes`) — collapses trailing quoted-reply text/HTML behind a
9290
+ localized show/hide toggle. `false` (the default) preserves the full body rendering.
8029
9291
 
8030
9292
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
8031
9293
 
8032
9294
  **CSS parts:** `base`, `headers`, `from-label`, `from`, `to-label`, `to`, `subject-label`, `subject`,
8033
9295
  `date-label`, `date`, `body`, `body-html`, `body-text`, `attachments`, `attachments-label`,
8034
- `attachment-list`, `attachment-item`, `spinner`, and `error`.
9296
+ `attachment-list`, `attachment-item`, `quoted` (a folded quoted-text block, hidden until expanded, only
9297
+ while `foldQuotes`), `quote-toggle` (the show/hide-quoted-text toggle button, only while `foldQuotes`),
9298
+ `spinner`, and `error`.
8035
9299
 
8036
9300
  **Optional peer dependencies:** install `postal-mime` and `dompurify` with
8037
9301
  `pnpm add postal-mime dompurify`. The component registers `message/rfc822` and falls back to
@@ -8087,19 +9351,48 @@ epub.js renders the reading area into its stable `mount` element, using an inter
8087
9351
  chapter content.
8088
9352
 
8089
9353
  **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.
9354
+ the reading region's accessible name. `location: string = ''` (not reflected — CFIs are long) is
9355
+ a CFI or spine href identifying the current reading position: set before the book finishes
9356
+ loading it's recorded and applied once ready, set after it applies immediately, and epub.js's own
9357
+ `relocated` event keeps it in sync with user navigation without re-triggering its own `display()`
9358
+ call. `anchorKinds` is a readonly `['cfi', 'text-quote']` (this viewer's supported `LyraAnchor.kind`
9359
+ values for the shared anchor-target contract).
9360
+
9361
+ **Methods:** `getToc()` resolves the EPUB's own navigation document (`book.navigation.toc`,
9362
+ populated once `book.ready` resolves) flattened into document-ordered `EbookTocItem[]` (`{ id,
9363
+ label, href, level }`, `level` starting at 1 for a top-level entry, `id` falling back to `href`
9364
+ when a navigation entry has none), `[]` before a book has loaded. `search(query)` resolves the
9365
+ match count across every spine section, in document order, via epub.js's own `item.load()`/
9366
+ `item.find()`/`item.unload()` (empty/whitespace query behaves like `clearSearch()`; a newer
9367
+ `search()` call or a `src` change aborts an in-flight scan); `searchNext()`/`searchPrevious()`
9368
+ advance/step back through matches (wrapping, resolving `false` when there are none); `clearSearch()`
9369
+ clears the query, matches, and painted search annotation.
9370
+
9371
+ **Events:** `lyra-render-error` with `detail.error` when fetching, opening, or rendering fails;
9372
+ `lyra-location-change` (`detail: { cfi, href }`) fired from epub.js's own `relocated` event;
9373
+ `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) from `search()`/`searchNext()`/
9374
+ `searchPrevious()`/`clearSearch()`.
8093
9375
 
8094
9376
  **CSS parts:** `base`, `toolbar`, `previous-button`, `next-button`, `previous-icon`, `next-icon`,
8095
- `mount`, and `error`.
9377
+ `mount`, `error`, and `announcer` (the visually-hidden `role="status"` region search results
9378
+ announce through).
8096
9379
 
8097
9380
  **Optional peer dependency:** install `epubjs` with `pnpm add epubjs`. The document-viewer registry
8098
- matches `application/epub+zip` and `.epub` filenames.
9381
+ matches `application/epub+zip` and `.epub` filenames, declaring `{ anchors: ['cfi', 'text-quote'],
9382
+ search: true, textSelect: true }` capabilities.
8099
9383
 
8100
9384
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
8101
9385
  `documentPreviewResourceTooLarge` message instead of the ebook.
8102
9386
 
9387
+ Adopts the shared anchor-target contract (`highlights`, `activeHighlightId`, `scrollToAnchor()`,
9388
+ events `lyra-highlight-activate`/`lyra-text-select`/`lyra-anchor-result`): a `cfi` anchor displays
9389
+ directly via `rendition.display()`; a `text-quote` anchor resolves by scanning the spine with
9390
+ epub.js's own `item.find()`, since chapter content lives inside epub.js-owned iframes rather than
9391
+ this component's own shadow DOM — `lyra-text-select` mirrors epub.js's own `selected` event for the
9392
+ same reason. `highlights` (kind `cfi`) paint via `rendition.annotations.highlight()` and are
9393
+ re-applied whenever the rendition is recreated (a `src` change, or a reconnect remount), since
9394
+ epub.js doesn't persist annotations across a fresh `renderTo()`.
9395
+
8103
9396
  ## `lyra-pptx-viewer`
8104
9397
 
8105
9398
  Best-effort client-side PPTX viewer backed by the optional `@aiden0z/pptx-renderer` peer. A
@@ -8149,11 +9442,28 @@ MIME type. Unknown values return a generic file result.
8149
9442
  Fetches an SVG document, sanitizes it with the optional `dompurify` peer, and renders it inline.
8150
9443
 
8151
9444
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
8152
- the scrollable body.
9445
+ the scrollable body. `zoomable: boolean = false` (reflected) — wraps the rendered content in an
9446
+ internal `<lyra-zoomable-frame>`. `false` (the default) preserves the exact pre-`zoomable` DOM — an
9447
+ inline thumbnail (e.g. in a chat stream) must not unexpectedly grow a focusable zoom-chrome viewport;
9448
+ an inspection surface opts in. `highlights: LyraHighlight[] = []` (attribute: false) — display-only
9449
+ `region` highlights painted over the rendered SVG. `activeHighlightId: string | null = null`
9450
+ (attribute `active-highlight-id`) — the `highlights` entry, if any, currently treated as active
9451
+ (`data-active` on its `region-highlight`). `anchorKinds` is a readonly `['region']` (this viewer's
9452
+ supported `LyraAnchor.kind` values for the shared anchor-target contract).
9453
+
9454
+ **Methods:** `scrollToAnchor(target)` — scrolls a `region` highlight (by id, or a `LyraAnchor` matched
9455
+ back to its owning `LyraHighlight` by reference) into view; resolves `false` when nothing matches, the
9456
+ anchor isn't `region`, or the document isn't loaded yet (no retry loop — a caller invoking this before
9457
+ `src` resolves simply gets `false`).
8153
9458
 
8154
9459
  **Events:** `lyra-render-error` with `detail.error` when fetching or sanitizing fails.
9460
+ `lyra-highlight-activate` (`detail: { id }`) — a region highlight was clicked or activated via
9461
+ Enter/Space.
8155
9462
 
8156
- **CSS parts:** `base`, `body`, `svg`, `spinner`, and `error`.
9463
+ **CSS parts:** `base`, `body`, `svg`, `spinner`, `error`, `highlight-layer` (wrapper around every
9464
+ rendered region highlight), `region-highlight` (one region highlight, `data-tone`, `data-active`),
9465
+ `frame-viewport`/`frame-content`/`frame-controls`/`frame-zoom-in`/`frame-zoom-out`/`frame-reset`
9466
+ (forwarded from the internal `<lyra-zoomable-frame>` while `zoomable`).
8157
9467
 
8158
9468
  **Optional peer dependency:** `dompurify`.
8159
9469
 
@@ -8178,23 +9488,44 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8178
9488
 
8179
9489
  ## `lyra-dataset-viewer`
8180
9490
 
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.
9491
+ Fetches tab-, pipe-, or delimiter-separated text and renders a virtualized, accessible table (a
9492
+ `role="table"` container with a sticky `role="row"` header, composed with `<lyra-virtual-list
9493
+ item-role="row">` for the body) using the optional `papaparse` peer. The document registry matches
9494
+ `.tsv`, `.psv`, and `.dat` filenames.
8183
9495
 
8184
- **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings.
9496
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with the
9497
+ header row always occupying row 1 (this component always parses with a header row, so the first row
9498
+ is never part of the virtualized body); `scrollToAnchor()` scrolls the addressed row into view via
9499
+ the virtualized list's `active-id`. `highlights` paint as a `part="cell-highlight"` cell wrapping a
9500
+ focusable `part="cell-highlight-action"` native button, keeping the ARIA table tree intact.
9501
+
9502
+ **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `anchorKinds` is
9503
+ a readonly `['cell-range']` (this viewer's supported `LyraAnchor.kind` values for the shared
9504
+ anchor-target contract).
9505
+
9506
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring search over
9507
+ every body cell's raw string value, ordered row then column (empty/whitespace query behaves like
9508
+ `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches (wrapping,
9509
+ resolving `false` when there are none); `clearSearch()` clears the query, matches, and cursor.
8185
9510
 
8186
9511
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
9512
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9513
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9514
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9515
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8187
9516
 
8188
- **CSS parts:** `base`, `body`, `table`, `spinner`, and `error`.
9517
+ **CSS parts:** `base`, `body`, `table`, `header-row`, `header-cell`, `data-row`, `cell`,
9518
+ `cell-highlight` (a `role="cell"` covered by a `highlights` entry; wraps the action button),
9519
+ `cell-highlight-action` (the native button filling a highlighted cell — focusable, emits
9520
+ `lyra-highlight-activate` on click or Enter/Space), `spinner`, and `error`.
8189
9521
 
8190
9522
  **Exports:** `DatasetTable` is `{ fields: string[]; rows: Record<string, string>[] }`.
8191
9523
 
8192
9524
  **Optional peer dependency:** `papaparse`.
8193
9525
 
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.
9526
+ Remote resources are capped at 25 MB, and the parsed table at 10,000 rows and 1,000 columns (the
9527
+ same shared default as `lyra-csv-viewer`/`lyra-spreadsheet-viewer`); exceeding either surfaces the
9528
+ localized `documentPreviewResourceTooLarge` message instead of the table.
8198
9529
 
8199
9530
  ## `lyra-contact-viewer`
8200
9531
 
@@ -8222,13 +9553,23 @@ Fetches a PDF and renders its pages with the optional `pdfjs-dist` peer. Pages a
8222
9553
  `lyra-virtual-list`, and PDF.js's selectable text layer is positioned over each rendered canvas.
8223
9554
 
8224
9555
  **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`.
9556
+ `zoom: number = 1` is clamped to `0.25`–`4`. `anchorKinds` is a readonly `['page', 'text-quote',
9557
+ 'region']` (this viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
8226
9558
 
8227
9559
  **Events:** `lyra-render-error` with `detail.error` when fetching, parsing, or rendering fails;
8228
9560
  `lyra-page-change` with `{ page, pageCount }`; and `lyra-zoom-change` with `{ zoom }`.
8229
9561
 
8230
9562
  **Methods:** `nextPage()`, `previousPage()`, `zoomIn()`, and `zoomOut()` update the corresponding
8231
- controlled state within its supported range.
9563
+ controlled state within its supported range. `getPageText(page)` resolves the raw reading-order text
9564
+ of one page (per-page LRU-cached, 64 pages), rejecting on no loaded document or an out-of-range page.
9565
+ `renderPageThumbnail(page, canvas, options?)` renders `page` into a caller-owned `canvas` at
9566
+ `options.width` CSS px (default 96), devicePixelRatio-aware, resolving `false` when not ready or out
9567
+ of range. `goToPage(page)` scrolls the virtualized list to `page`, resolving `true` once mounted (or
9568
+ `false` for an out-of-range value, without changing `page`). `getOutline()` resolves the document's
9569
+ table of contents as `PdfOutlineItem[]` (`{ title, page?, children? }`), `[]` when there is none.
9570
+ `search(query)` resolves the match count across all pages (empty/whitespace query behaves like
9571
+ `clearSearch()`); `searchNext()` and `searchPrevious()` advance/step back through matches (wrapping,
9572
+ resolving `false` when there are none); `clearSearch()` clears the query, matches, and painted marks.
8232
9573
 
8233
9574
  **CSS parts:** `base`, `toolbar`, `page-indicator`, `zoom-indicator`, `pages`, `page`, `text-layer`,
8234
9575
  `spinner`, and `error`.
@@ -8245,14 +9586,31 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8245
9586
  Fetches and renders `.xlsx` and `.xls` workbooks with the optional `xlsx` (SheetJS) peer. Multiple
8246
9587
  worksheets render through a `<lyra-tabs>` switcher, and body rows use `<lyra-virtual-list>`.
8247
9588
 
8248
- **Properties:** `src` and `name` are strings.
9589
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses one sheet's raw grid, 1-based, with
9590
+ its header row included, resolving the target sheet from the anchor's own `sheet` field (falling
9591
+ back to a `Sheet!`-prefixed `range`, then the active sheet); `scrollToAnchor()` switches
9592
+ `<lyra-tabs>`'s active tab first when needed, then scrolls the addressed row/column into view.
9593
+ `highlights` paint as a focusable `part="cell-highlight"`.
9594
+
9595
+ **Properties:** `src` and `name` are strings. `anchorKinds` is a readonly `['cell-range']` (this
9596
+ viewer's supported `LyraAnchor.kind` values for the shared anchor-target contract).
9597
+
9598
+ **Methods:** `search(query)` resolves the match count across every sheet's stringified cell values,
9599
+ ordered sheet then row then column, switching tabs as navigation crosses sheets (empty/whitespace
9600
+ query behaves like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through
9601
+ matches (wrapping, resolving `false` when there are none); `clearSearch()` clears the query,
9602
+ matches, and painted marks.
8249
9603
 
8250
9604
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
9605
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9606
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9607
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9608
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8251
9609
 
8252
- **CSS parts:** `base`, `tabs`, `sheet`, `header-row`, `data-row`, `cell`, `rows`, `spinner`, and
8253
- `error`.
9610
+ **CSS parts:** `base`, `tabs`, `sheet`, `header-row`, `data-row`, `cell`, `cell-highlight` (a cell
9611
+ covered by a `highlights` entry), `rows`, `spinner`, and `error`.
8254
9612
 
8255
- **Optional peer dependency:** install `xlsx` with `pnpm add xlsx`. The registry matches the official
9613
+ **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
9614
  `.xlsx` and `.xls` MIME types and filename extensions.
8257
9615
 
8258
9616
  Remote resources are capped at 25 MB, and each parsed sheet at 10,000 rows and 1,000 columns;
@@ -8263,12 +9621,30 @@ the workbook.
8263
9621
 
8264
9622
  Fetches CSV text, parses quoted fields with the optional `papaparse` peer, and virtualizes body rows.
8265
9623
 
9624
+ Adopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with the
9625
+ header row included whenever `has-header-row` is set; `scrollToAnchor()` scrolls the addressed
9626
+ row/column into view via the virtualized list's `active-id`. `highlights` paint as a focusable
9627
+ `part="cell-highlight"`.
9628
+
8266
9629
  **Properties:** `src` and `name` are strings. `hasHeaderRow: boolean = true` (attribute
8267
9630
  `has-header-row`) controls whether the first parsed row is rendered as a sticky header.
9631
+ `anchorKinds` is a readonly `['cell-range']` (this viewer's supported `LyraAnchor.kind` values for
9632
+ the shared anchor-target contract).
9633
+
9634
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring match over
9635
+ the same stringified cell values `cell()` renders, ordered row then column (empty/whitespace query
9636
+ behaves like `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches
9637
+ (wrapping, resolving `false` when there are none); `clearSearch()` clears the query, matches, and
9638
+ painted marks.
8268
9639
 
8269
9640
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing reports an error.
9641
+ `lyra-highlight-activate` (`detail: { id }`) — a `highlights` cell was clicked or activated via
9642
+ Enter/Space. `lyra-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
9643
+ `scrollToAnchor()` call. `lyra-search-change` (`detail: { query, matchCount, activeIndex }`) — from
9644
+ `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()`.
8270
9645
 
8271
- **CSS parts:** `base`, `sheet`, `header-row`, `data-row`, `cell`, `rows`, `spinner`, and `error`.
9646
+ **CSS parts:** `base`, `sheet`, `header-row`, `data-row`, `cell`, `cell-highlight` (a cell covered by
9647
+ a `highlights` entry), `rows`, `spinner`, and `error`.
8272
9648
 
8273
9649
  **Optional peer dependency:** install `papaparse` with `pnpm add papaparse`. The registry matches
8274
9650
  `text/csv` and `.csv` filenames.
@@ -8946,6 +10322,41 @@ Groups avatars and collapses excess members into a localized overflow indicator.
8946
10322
  `max`, `shape`, `size`, and `tone`. The default slot accepts avatar elements. **CSS parts:** `base`,
8947
10323
  `avatars`, and `overflow`.
8948
10324
 
10325
+ ## `lyra-emoji-picker`
10326
+
10327
+ A searchable, keyboard-navigable, form-associated emoji picker. `groups` is fully consumer-suppliable
10328
+ — the component ships no emoji data of its own — in the same "zero/optional-peer dependency" spirit
10329
+ as `<lyra-lite-chart>`/`<lyra-heatmap>`; an optional convenience auto-loader fetches a default set on
10330
+ connect from the `emoji-picker-element-data` peer, but only when `groups` hasn't already been
10331
+ supplied (an explicit empty array still counts as supplied and skips the auto-load).
10332
+
10333
+ **Properties:** the shared form properties `name`, `value`, `disabled`, and `required`, plus
10334
+ `groups: EmojiPickerGroup[] = []` (attribute: false) — `EmojiPickerGroup { key, label, emojis:
10335
+ EmojiPickerItem[] }`, `EmojiPickerItem { emoji, name, shortcodes? }`; the search field matches `name`
10336
+ and every `shortcodes` entry, case-insensitively. Empty (the default, before the auto-loader
10337
+ resolves) renders just the search input and the empty state. `accessibleLabel` (`aria-label`)
10338
+ forwards a host-supplied accessible name to the internal `role="listbox"` grid; empty falls back to
10339
+ the localized default grid label.
10340
+
10341
+ **Events:** `lyra-change` with `detail: { emoji }` (an emoji was picked — click, or Enter/Space on
10342
+ the active grid cell; also sets `value`), plus the shared form `input`, `change`, `focus`, and `blur`.
10343
+
10344
+ **Keyboard:** the grid is a roving-tabindex listbox (a single Tab stop — only the active emoji is
10345
+ tabbable). ArrowLeft/ArrowRight step the active item backward/forward following reading direction
10346
+ (swapped under RTL), ArrowUp/ArrowDown move by one visual row (measured from the live wrap layout),
10347
+ Home/End jump to the first/last item, and Enter/Space picks the active item. The search input is a
10348
+ `role="combobox"` over the same listbox: the arrow keys and Enter also work while focus stays in
10349
+ the input, with `aria-activedescendant` tracking the active option. Hovering an emoji with the
10350
+ pointer also moves the active item to it.
10351
+
10352
+ **CSS parts:** `base`, `search` (`role="combobox"`), `grid` (`role="listbox"`), `group-label`,
10353
+ `emoji` (each emoji's own `role="option"` button), `empty` (shown when the search matches nothing).
10354
+
10355
+ **Optional peer dependency:** install `emoji-picker-element-data` with
10356
+ `pnpm add emoji-picker-element-data` for the built-in auto-loaded default emoji set — omit it and
10357
+ supply `groups` directly instead. The loader never throws; a missing or failed peer logs one
10358
+ `console.warn` and simply leaves `groups` empty.
10359
+
8949
10360
  ## `lyra-include`
8950
10361
 
8951
10362
  Loads HTML or text from `src` into the component. **Properties:** `src` and `mode` (`html` or `text`).
@@ -9054,3 +10465,1130 @@ These apply across the whole library rather than to any one component:
9054
10465
  - **RTL.** Components generally rely on CSS logical properties to flip layout for free; `lyra-split`
9055
10466
  and `lyra-time-range` additionally consult `internal/rtl.ts`'s `isRtl()` to mirror the physical
9056
10467
  drag-direction/arrow-key math that logical properties alone don't cover.
10468
+
10469
+ ## `lyra-audio-visualizer`
10470
+
10471
+ A presentational, canvas-drawn voice-activity visualization (bars or waveform) — the
10472
+ LiveKit-BarVisualizer counterpart for this library. Driven by a `MediaStream` (lazily wired to a
10473
+ WebAudio `AnalyserNode`), a numeric `level` for hosts that already compute levels (e.g.
10474
+ `<lyra-push-to-talk>`'s `lyra-level`), or `state` alone for an ambient animation when no real signal
10475
+ exists. A real signal (`stream` or `level`) always drives amplitude regardless of
10476
+ `prefers-reduced-motion`; only the signal-less ambient animation is throttled under reduced motion.
10477
+
10478
+ **Properties:** `stream: MediaStream | null = null` (attribute: false), `level: number | null = null`,
10479
+ `state: 'idle' | 'listening' | 'thinking' | 'speaking' = 'idle'` (reflected), `variant: 'bars' |
10480
+ 'waveform' = 'bars'` (reflected), `barCount: number = 5` (attribute `bar-count`), `gain: number = 1`,
10481
+ and `label: string = ''`.
10482
+
10483
+ **Methods:** `refreshTheme()` re-reads themeable custom properties after a runtime theme change.
10484
+
10485
+ **CSS parts:** `base` (the root wrapper) and `canvas` (the drawing surface, `aria-hidden`; the host
10486
+ itself carries `role="img"` and the accessible name).
10487
+
10488
+ **Themeable custom properties:** `--lyra-audio-visualizer-color` (default `--lyra-color-brand` —
10489
+ active bar/waveform color) and `--lyra-audio-visualizer-quiet-color` (default
10490
+ `--lyra-color-brand-quiet` — inactive/idle color).
10491
+
10492
+ ## `lyra-branch-picker`
10493
+
10494
+ The "‹ 2 / 5 ›" navigator across regenerated/edited variants of one message. Pure controlled: it
10495
+ never mutates its own `index` — the same contract `<lyra-pagination>` already establishes for
10496
+ `page`. The host listens for `lyra-branch-change`, swaps the displayed branch content, and applies
10497
+ the new `index` back. Renders nothing at all while `count < 2`, so a host can bind it unconditionally
10498
+ on every message regardless of whether that message actually has multiple branches yet.
10499
+
10500
+ **Properties:** `index: number = 0` (reflected) and `count: number = 1` (reflected) — the current
10501
+ 0-based branch and the total branch count. `label: string = ''`.
10502
+
10503
+ **Methods:** `focus()` and `blur()` forward to the group wrapper.
10504
+
10505
+ **Events:** `lyra-branch-change` — a branch navigation was requested. `detail: { index }`, always a
10506
+ valid target (never past either bound); the consumer applies `index` after switching the displayed
10507
+ branch content.
10508
+
10509
+ **CSS parts:** `base` (the group wrapper, `role="group"`), `previous-button`, `next-button`, and
10510
+ `position` (the visible "2 / 5" text).
10511
+
10512
+ ## `lyra-compare-panel`
10513
+
10514
+ Side-by-side A/B output comparison with a winner vote (LMSYS-arena / LangSmith-pairwise style): two
10515
+ slotted panes, a vote bar, synchronized reading.
10516
+
10517
+ **Properties:** `labelA: string = ''` (attribute `label-a`) and `labelB: string = ''` (attribute
10518
+ `label-b`) — pane headings. `vote: 'a' | 'b' | 'tie' | 'both-bad' | null = null` (reflected) — the
10519
+ recorded winner, host-writable to reflect a previously-recorded vote back. `itemId: string = ''`
10520
+ (attribute `item-id`) — an opaque id round-tripped through `lyra-vote`. `hideTie: boolean = false`
10521
+ (attribute `hide-tie`) and `hideBothBad: boolean = false` (attribute `hide-both-bad`) hide the
10522
+ corresponding vote button. `syncScroll: boolean = false` (attribute `sync-scroll`) links both panes'
10523
+ scroll position.
10524
+
10525
+ **Slots:** `a` (the first output — any content, a chat message, markdown, a viewer), `b` (the second
10526
+ output), and `prompt` (optional shared-input header above both panes).
10527
+
10528
+ **Events:** `lyra-vote` — `detail: { choice, itemId }`.
10529
+
10530
+ **CSS parts:** `base` (the outer wrapper), `prompt` (the optional prompt header, hidden when the
10531
+ `prompt` slot is empty), `panes` (the row, or under 640px column, wrapping both panes), `pane-a`,
10532
+ `pane-b` (each pane's labeled scroll region), `pane-header` (a pane's visible heading), `vote-bar`
10533
+ (the `role="group"` row of vote buttons), `vote-button` (one vote button), and `live-region` (the
10534
+ internal vote-announcement live region).
10535
+
10536
+ ## `lyra-highlight-layer`
10537
+
10538
+ A presentational overlay that paints highlight rectangles (percent-of-box coordinates) over
10539
+ positioned content and owns their activation, active/flash styling, and keyboard access. `items`
10540
+ order is the caller's own reading order; the layer does not re-sort geometrically. Fills its nearest
10541
+ positioned ancestor.
10542
+
10543
+ **Properties:** `items: HighlightLayerItem[] = []` (attribute: false), `activeId: string | null =
10544
+ null` (attribute `active-id`), and `interactive: boolean = true` (reflected) — gates click/keyboard
10545
+ activation.
10546
+
10547
+ **Methods:** `flash(id)` briefly re-triggers the flash styling for an already-rendered rect (e.g. a
10548
+ re-click of the same source citation).
10549
+
10550
+ **Events:** `lyra-highlight-activate` — a rect was activated (click, or Enter/Space while focused).
10551
+ `detail: { id }`.
10552
+
10553
+ **CSS parts:** `base` (the absolutely-positioned overlay, inset 0) and `rect` (one highlight
10554
+ rectangle; carries `data-tone`/`data-active`/`data-flash` state attributes).
10555
+
10556
+ ## `lyra-message-actions`
10557
+
10558
+ The per-message action toolbar for `lyra-chat-message`'s `actions` slot: opt-in built-ins (copy /
10559
+ regenerate / edit / feedback) that emit intent events, plus a default slot for custom controls (e.g.
10560
+ a slotted `lyra-branch-picker`). `role="toolbar"` with WAI-ARIA APG roving-tabindex; ArrowLeft/
10561
+ ArrowRight (RTL-aware) plus Home/End move focus across every stop — built-ins and slotted controls
10562
+ alike — via `.focus()`. Only the plain-button built-ins (`regenerate`/`edit`) get their `tabindex`
10563
+ toggled by this component itself; a composite child (`lyra-copy-button`, the `feedback` built-in, any
10564
+ slotted custom element) remains independently reachable via the page's native Tab order alongside the
10565
+ toolbar's single roving stop, since a shadow-root-internal focusable element can't be suppressed from
10566
+ outside its own component.
10567
+
10568
+ **Properties:** `controls: MessageActionControl[] = []` (attribute: false, each `'copy' |
10569
+ 'regenerate' | 'edit' | 'feedback'`) — which built-ins render, in that order. `copyText: string = ''`
10570
+ (attribute `copy-text`) — required for the `copy` built-in to render at all. `feedbackValue: 'up' |
10571
+ 'down' | null = null` (attribute `feedback-value`) — forwarded to the embedded, thumbs-only
10572
+ `lyra-message-feedback` (its `reasons`/`commentable`/`detailFor` are never forwarded, so its detail
10573
+ panel never opens). `revealOnHover: boolean = false` (reflected, attribute `reveal-on-hover`) — hides
10574
+ the bar until the closest `lyra-chat-message` ancestor is hovered or a control inside has focus.
10575
+ `label: string = ''` — accessible name override for the toolbar. `accessibleLabel: string | null =
10576
+ null` (attribute `aria-label`) — overrides the toolbar's computed accessible name, winning over
10577
+ `label` and the localized default; attribute-reflects from a host-level `aria-label`.
10578
+
10579
+ **Events:** `lyra-regenerate`/`lyra-edit` — a built-in was activated, no detail. `lyra-copy` —
10580
+ `detail: { text }`, surfaced by the embedded `lyra-copy-button` (bubbles/composed already, not
10581
+ re-emitted). `lyra-change`/`lyra-submit` — bubble unchanged from the embedded, thumbs-only
10582
+ `lyra-message-feedback`.
10583
+
10584
+ **Slots:** default — additional controls (e.g. `lyra-copy-button`, `lyra-icon-button`,
10585
+ `lyra-branch-picker`) appended after the built-ins; they participate in the toolbar's arrow-key
10586
+ navigation.
10587
+
10588
+ **CSS parts:** `base` (the toolbar, `role="toolbar"`), `copy-button` (the embedded
10589
+ `lyra-copy-button`), `regenerate-button`, `edit-button`, and `feedback` (the embedded
10590
+ `lyra-message-feedback`).
10591
+
10592
+ ## `lyra-message-feedback`
10593
+
10594
+ Thumbs up/down for one assistant message, with an optional inline detail step (categorical reason
10595
+ chips + a free-text comment) that opens as a disclosure directly below the thumbs. Emits; never
10596
+ persists — a host reflects a previously-recorded rating back via `value` (+ `disabled` for a
10597
+ read-only display). Activating the pressed thumb again toggles it off to `null` unless its own detail
10598
+ panel is currently open, in which case that click re-opens the panel instead.
10599
+
10600
+ **Properties:** `value: 'up' | 'down' | null = null` (reflected), `reasons: MessageFeedbackReason[] =
10601
+ []` (attribute: false, each `{ id, label }`), `commentable: boolean = false` (reflected) adds a
10602
+ free-text comment field, `detailFor: 'down' | 'both' = 'down'` (attribute `detail-for`) — which
10603
+ rating opens the detail panel, and `disabled: boolean = false` (reflected) for a read-only display.
10604
+
10605
+ **Methods:** `focus()` focuses the thumb matching the current `value` (the up thumb when `null`);
10606
+ `blur()` blurs both thumbs.
10607
+
10608
+ **Events:** `lyra-change` — `detail: { value }`, fired when a thumb's rating changes or clears.
10609
+ `lyra-submit` — `detail: { value, reasonIds, comment }`, fired by the panel's submit button.
10610
+
10611
+ **CSS parts:** `base` (the root), `thumbs` (wrapper around both thumb buttons), `up-button`,
10612
+ `down-button`, `panel` (the inline detail disclosure, only rendered when `reasons` is non-empty or
10613
+ `commentable` is set), `reasons` (the reason-chip group), `comment` (the comment `<textarea>`), and
10614
+ `submit-button`.
10615
+
10616
+ ## `lyra-page-rail`
10617
+
10618
+ A virtualized vertical thumbnail rail for page-addressed documents, with per-page highlight heat
10619
+ markers. Two modes: **wired** (`viewer`/`for` supply a live page source, e.g. `<lyra-pdf-viewer>` —
10620
+ thumbnails render lazily as rows materialize, and the rail tracks page/count from the viewer's own
10621
+ events) and **mediated** (`page-count`/`page` are host-bound directly, rows render a placeholder
10622
+ glyph — still a fully functional pager). In wired mode the viewer's `page` is the single source of
10623
+ truth.
10624
+
10625
+ **Properties:** `viewer: PageThumbnailSource | null = null` (attribute: false) — the wired viewer.
10626
+ `for: string = ''` — an id selector alternative to setting `viewer` directly. `pageCount: number = 0`
10627
+ (attribute `page-count`) and `page: number = 1` (reflected) — mediated-mode page state.
10628
+ `highlights: LyraHighlight[] = []` (attribute: false) — drives the per-page heat markers.
10629
+ `thumbWidth: number = 96` (attribute `thumb-width`) and `label: string = ''`.
10630
+
10631
+ **Events:** `lyra-page-select` — a page row was activated (click, or Enter/Space on a focused row).
10632
+ `detail: { page }`. In wired mode the rail also sets `viewer.page` itself.
10633
+
10634
+ **CSS parts:** `base` (the rail), `pages` (the embedded `<lyra-virtual-list>`), `page` (one page
10635
+ button), `thumbnail` (the thumbnail canvas wrapper), `page-number` (the visible page number), `heat`
10636
+ (the heat-marker cluster), and `heat-dot` (one tone-colored heat marker, or the `+n` overflow
10637
+ marker).
10638
+
10639
+ **Themeable custom properties:** `--lyra-page-rail-height` (default `var(--lyra-size-24rem)`) — block
10640
+ size of the virtualized rail.
10641
+
10642
+ ## `lyra-push-to-talk`
10643
+
10644
+ A mic capture button owning the full `getUserMedia` + `MediaRecorder` lifecycle: permission request,
10645
+ recording, optional chunked streaming, teardown. The one place in this library that touches the
10646
+ microphone — no SDK, no LiveKit/ElevenLabs import, native browser APIs only. `mode="hold"` (the
10647
+ default) is a press-and-hold gesture; `mode="toggle"` is click-to-start/click-to-stop with
10648
+ `aria-pressed`. Escape cancels the in-progress take in either mode.
10649
+
10650
+ **Properties:** `mode: 'hold' | 'toggle' = 'hold'` (reflected), `timesliceMs: number = 0` (attribute
10651
+ `timeslice-ms`), `mimeType: string = ''` (attribute `mime-type`), `deviceId: string = ''` (attribute
10652
+ `device-id`), `audioConstraints?: MediaTrackConstraints` (attribute: false), `levelEvents: boolean =
10653
+ false` (attribute `level-events`), `maxDurationMs: number = 0` (attribute `max-duration-ms`),
10654
+ `showTimer: boolean = true` (attribute `show-timer`), `disabled: boolean = false` (reflected), and
10655
+ readonly `state: 'idle' | 'requesting' | 'denied' | 'recording' | 'error' = 'idle'` (reflected to
10656
+ `data-state`), and readonly `stream: MediaStream | null`.
10657
+
10658
+ **Methods:** `start()`, `stop()`, and `cancel()` drive the capture lifecycle imperatively (mirroring
10659
+ the pointer/keyboard gestures).
10660
+
10661
+ **Slots:** `icon` (replaces the default mic glyph) and `recording-icon` (replaces the default
10662
+ recording-state pulse glyph).
10663
+
10664
+ **Events:** `lyra-record-start` (`detail: { stream }`), `lyra-record-chunk` (`detail: { blob }`, only
10665
+ when `timeslice-ms > 0`), `lyra-record-stop` (`detail: { blob, durationMs }`), `lyra-record-cancel`
10666
+ (no detail), `lyra-record-error` (`detail: { error }`), `lyra-level` (`detail: { level }`, opt-in via
10667
+ `level-events`), and `lyra-state-change` (`detail: { state }`).
10668
+
10669
+ **CSS parts:** `trigger` (the capture button), `icon`, `pulse` (rendered only while recording),
10670
+ `timer` (the `M:SS` elapsed-time readout, only while recording and `show-timer`), and `status`
10671
+ (visible status text for the `requesting`/`denied`/`error`/unsupported states).
10672
+
10673
+ ## `lyra-rubric-form`
10674
+
10675
+ A configurable annotation rubric (LangSmith annotation-queue style): score, category, and
10676
+ freeform-comment keys with a submit-and-next flow for working through an eval queue. Each
10677
+ `RubricKey.type` routes to an existing sibling control: `score` renders `<lyra-segmented>` or
10678
+ `<lyra-slider>`; `category` renders `<lyra-select>` or `<lyra-checkbox-group>` (`multiple`); `comment`
10679
+ renders `<lyra-textarea>`.
10680
+
10681
+ **Properties:** `keys: RubricKey[] = []` (attribute: false, each `{ key, type, label?, description?,
10682
+ required?, min?, max?, step? }`), `value: RubricValue = {}` (attribute: false), `itemId: string = ''`
10683
+ (attribute `item-id`, reflected), `hasNext: boolean = false` (attribute `has-next`), `skippable:
10684
+ boolean = false`, and the shared form properties `name` and `disabled`. `errors: Record<string,
10685
+ string>` is the current per-key validation-message state.
10686
+
10687
+ **Slots:** `actions` — extra host controls rendered in the footer beside Submit/Skip.
10688
+
10689
+ **Events:** `lyra-input` (`detail: { value }`), `lyra-validity-change` (`detail: { valid, errors }`,
10690
+ fired only on an actual change), `lyra-submit` (`detail: { value, itemId }`), and `lyra-skip`
10691
+ (`detail: { itemId }`, `skippable` only).
10692
+
10693
+ **CSS parts:** `base` (the outer wrapper), `field` (one key's wrapper), `label`, `description`,
10694
+ `scale` (the rendered score/category/comment control's wrapper), `error` (a field-level validation
10695
+ message), `footer`, `submit`, `skip` (only rendered when `skippable`), `empty` (shown when `keys` has
10696
+ no entries), and `unsupported` (the fallback note for a key whose `type` is outside the three
10697
+ supported ones).
10698
+
10699
+ ## `lyra-span-waterfall`
10700
+
10701
+ The horizontal-timeline projection of the same `LyraSpan[]` `<lyra-trace-tree>` consumes: a time
10702
+ axis, one row per span in start order, status-toned bars (Langfuse timeline / Temporal
10703
+ event-history style).
10704
+
10705
+ **Properties:** `spans: LyraSpan[] = []` (attribute: false), `activeSpanId: string | null = null`
10706
+ (attribute `active-span-id`), `viewStartMs: number | null = null` (attribute `view-start-ms`) and
10707
+ `viewEndMs: number | null = null` (attribute `view-end-ms`) — override the auto-computed time
10708
+ window, `hideAxis: boolean = false` (attribute `hide-axis`), and `label: string = ''`.
10709
+
10710
+ **Events:** `lyra-span-select` — `detail: { id }`, a bar/row was activated (click, Enter, Space).
10711
+
10712
+ **CSS parts:** `base`, `axis` (the time-ruler row, hidden when `hideAxis`), `tick`, `tick-label`,
10713
+ `row`, `name` (the row's name gutter), `bar-track`, `bar` (the interactive, focusable status-toned
10714
+ bar), `meta` (secondary row info, shown inline under 480px), `status-text`, `duration`, `empty` (shown
10715
+ when `spans` is empty), and `live-region`.
10716
+
10717
+ **Themeable custom properties:** `--lyra-span-waterfall-name-width` (default `8rem`) and
10718
+ `--lyra-span-waterfall-stripe-speed` (a `running` span's striped-bar animation duration; defaults to
10719
+ `--lyra-transition-ambient`).
10720
+
10721
+ ## `lyra-task-list`
10722
+
10723
+ A live, collapsible tracker for an agent's plan: ordered steps with per-step lifecycle status and one
10724
+ level of nested sub-steps, embedded in the transcript. `items` is controlled and never mutated by this
10725
+ component. Unlike `<lyra-stepper>`'s single-`current` navigation, task-list is a read-only status
10726
+ report: several steps may be `running` at once, there is no selection, and status changes are
10727
+ announced through an internal `<lyra-live-region>`.
10728
+
10729
+ **Properties:** `items: TaskItem[] = []` (attribute: false, each `{ id, label, status, detail?,
10730
+ children? }` where `status` is `'pending' | 'running' | 'success' | 'error'`), `label: string =
10731
+ 'Tasks'`, `expanded: boolean = true` (reflected), and `collapsible: boolean = true`.
10732
+
10733
+ **Slots:** `detail-<id>` — dynamic, one per item id (e.g. `slot="detail-step-3"`); rich detail under
10734
+ that item's label, typically a `<lyra-tool-call-chip>` or file `<lyra-chip>`.
10735
+
10736
+ **Events:** `lyra-toggle` — the header was activated, expanding or collapsing the panel. `detail: {
10737
+ expanded }`.
10738
+
10739
+ **CSS parts:** `base`, `header` (a `<button>` when `collapsible`, a plain heading otherwise), `label`,
10740
+ `summary` (the visible "N of M completed" summary, top-level items only), `toggle` (the chevron
10741
+ indicator, only rendered when `collapsible`), `body` (the list of items, `hidden` while collapsed),
10742
+ `item` (`role="listitem"`; carries `data-status`/`data-id`/`data-depth`), `status-icon`, `item-label`,
10743
+ `item-detail`, and `item-children` (the nested `role="list"` wrapper around a top-level item's
10744
+ children).
10745
+
10746
+ **Themeable custom properties:** `--lyra-task-list-spin` (default `1s linear`) — running-status icon
10747
+ spin animation duration/timing.
10748
+
10749
+ ## `lyra-terminal`
10750
+
10751
+ A read-only ANSI console for streamed agent/tool output. Not a PTY: no stdin/keystroke handling, no
10752
+ cursor-addressed full-screen apps.
10753
+
10754
+ **Properties:** `content: string = ''` — initial/replaceable buffer content, parsed for ANSI/SGR
10755
+ codes. `maxScrollback: number = 5000` (attribute `max-scrollback`), `follow: boolean = true`
10756
+ (reflected) — stick-to-bottom, `wrap: boolean = true` (reflected), `copyable: boolean = true`
10757
+ (reflected) and `downloadable: boolean = false` (reflected) toggle the toolbar buttons, `filename:
10758
+ string = 'terminal.log'`, `announceOutput: boolean = false` (attribute `announce-output`),
10759
+ `accessibleLabel: string = ''` (attribute `aria-label`), `highlights: LyraHighlight[] = []` (attribute:
10760
+ false), and `activeHighlightId: string | null = null` (attribute: false). `anchorKinds` is a readonly
10761
+ `['page', 'text-quote', 'region']` for the shared anchor-target contract.
10762
+
10763
+ **Methods:** `write(text)` appends ANSI-parsed text to the buffer. `clear()` empties the buffer.
10764
+ `scrollToBottom()` and `scrollToAnchor(anchor)` control scroll position. `search(query)`,
10765
+ `searchNext()`, `searchPrevious()`, and `clearSearch()` drive in-buffer text search. `getPlainText()`
10766
+ returns the SGR-stripped plain text of the whole buffer.
10767
+
10768
+ **Events:** `lyra-copy` (`detail: { text }`), `lyra-download` (`detail: { filename }`),
10769
+ `lyra-follow-change` (`detail: { following }`), `lyra-search-change` (`detail: { query, matchCount,
10770
+ activeIndex }`), `lyra-highlight-activate` (`detail: { id }`), and `lyra-text-select` (`detail: {
10771
+ text, anchor, rects }`).
10772
+
10773
+ **CSS parts:** `base`, `toolbar` (only rendered when copy/download are enabled), `copy-button`,
10774
+ `download-button`, `viewport` (the `role="log"` scrollable region), `line` (one rendered line; carries
10775
+ `data-line-number`/`data-match`/`data-highlight-tone`), `jump-to-latest` (shown while `follow` is
10776
+ disengaged and new output has arrived), and `announcer` (the visually-hidden `role="status"` region
10777
+ used when `announce-output` is set).
10778
+
10779
+ ## `lyra-trace-tree`
10780
+
10781
+ A collapsible span hierarchy for one agent/LLM trace (Langfuse/LangSmith run-tree style): kind icon,
10782
+ name, status, an inline duration bar on the shared trace time scale, and optional tokens/cost
10783
+ columns. Consumes the same `LyraSpan[]` as `<lyra-span-waterfall>`.
10784
+
10785
+ **Properties:** `spans: LyraSpan[] = []` (attribute: false), `activeSpanId: string | null = null`
10786
+ (attribute `active-span-id`), `label: string = ''`, `showTokens: boolean = false` (attribute
10787
+ `show-tokens`), `showCost: boolean = false` (attribute `show-cost`), and `hideBars: boolean = false`
10788
+ (attribute `hide-bars`).
10789
+
10790
+ **Methods:** `expandAll()` and `collapseAll()` set every row's expanded state at once.
10791
+
10792
+ **Events:** `lyra-span-select` (`detail: { id }`, a row was activated) and `lyra-span-toggle`
10793
+ (`detail: { id, expanded }`, a row was expanded or collapsed).
10794
+
10795
+ **CSS parts:** `base` (`role="tree"`), `header` (the column-header row, only when
10796
+ `showTokens`/`showCost`), `row` (`role="treeitem"`), `toggle`, `icon`, `name`, `detail`, `status-text`,
10797
+ `duration`, `tokens-in`, `tokens-out` (when `showTokens`), `cost` (when `showCost`), `bar-track`,
10798
+ `bar`, `empty` (shown when `spans` is empty), and `live-region`.
10799
+
10800
+ ## `lyra-file-tree`
10801
+
10802
+ A file-explorer preset over `<lyra-tree>` + `<lyra-file-icon>`: path-keyed nodes with
10803
+ git-status/diff-count badges, lazy directory loading, and select/open events.
10804
+
10805
+ **Properties:** `nodes: FileTreeNode[] = []` (attribute: false), `selectedPath: string | null = null`
10806
+ (attribute `selected-path`), and `label: string = ''`.
10807
+
10808
+ **Methods:** `setChildren(path, children)` supplies a lazily-loaded directory's children.
10809
+ `revealPath(path)` expands every ancestor directory and scrolls the target row into view, resolving
10810
+ `true` once found. `expandAll()` and `collapseAll()` forward to the underlying `<lyra-tree>`.
10811
+
10812
+ **Events:** `lyra-file-select` (`detail: { path, node }`, a row was activated), `lyra-file-open`
10813
+ (`detail: { path, node }`, Enter/click on an already-selected file row), and `lyra-load-children`
10814
+ (`detail: { path }`, a lazy unloaded directory expanded).
10815
+
10816
+ **CSS parts:** `base` — the root wrapper.
10817
+
10818
+ ## `lyra-activity-feed`
10819
+
10820
+ An append-only streaming log of granular agent actions ("Searching the web…", "Read
10821
+ src/index.ts"), collapsing to a localized "Completed N steps" summary once the run is over. Entries
10822
+ never change state once added — a step whose status mutates in place belongs to `<lyra-task-list>`
10823
+ instead. Implements the shared follow (stick-to-bottom) contract. At/above `virtualizeThreshold`
10824
+ entries, the body renders through an internal `<lyra-virtual-list>` instead of a plain keyed list.
10825
+
10826
+ **Properties:** `entries: ActivityEntry[] = []` (attribute: false), `mode: 'live' | 'post-hoc' =
10827
+ 'live'` (reflected), `follow: boolean = true` (reflected), `expanded: boolean = false` (reflected),
10828
+ `label: string = 'Activity'`, `showTimestamps: boolean = false` (attribute `show-timestamps`),
10829
+ `formatTimestamp?: (date: Date) => string` (attribute: false), and `virtualizeThreshold: number =
10830
+ 200` (attribute `virtualize-threshold`).
10831
+
10832
+ **Events:** `lyra-toggle` (`detail: { expanded }`, the header was activated) and
10833
+ `lyra-follow-change` (`detail: { following }`, `follow` released or re-engaged).
10834
+
10835
+ **CSS parts:** `base`, `header` (a `<button>`), `status-dot` (pulses while `mode="live"`),
10836
+ `summary`, `toggle`, `body` (the scrollable region, or the internal virtual-list), `entry` (carries
10837
+ `data-tone`), `entry-icon`, `entry-text`, and `entry-timestamp` (only while `showTimestamps` and a
10838
+ valid `timestamp` is set).
10839
+
10840
+ **Themeable custom properties:** `--lyra-activity-feed-max-height` (default `16rem`) — cap on how
10841
+ tall the expanded body grows before it scrolls internally.
10842
+
10843
+ ## `lyra-commit-card`
10844
+
10845
+ A compact commit summary (subject, author/time, diffstat, per-file changes) that links file rows out
10846
+ to a diff view.
10847
+
10848
+ **Properties:** `hash: string = ''`, `message: string = ''`, `author: string = ''`, `timestamp?:
10849
+ number` (attribute: false), `files: CommitFileChange[] = []` (attribute: false), `filesCollapsed:
10850
+ boolean = true` (attribute `files-collapsed`, reflected), and `copyable: boolean = true` (reflected).
10851
+
10852
+ **Slots:** `actions` — trailing header controls (e.g. an "open PR" button).
10853
+
10854
+ **Events:** `lyra-file-select` (`detail: { path }`), `lyra-toggle` (`detail: { collapsed }`), and
10855
+ `lyra-copy` (`detail: { text }`, the full hash was copied).
10856
+
10857
+ **CSS parts:** `base`, `subject`, `body`, `hash`, `meta`, `author`, `time`, `diffstat`, `additions`,
10858
+ `deletions`, `files-toggle`, `file` (carries `data-status`), `file-path`, `file-additions`,
10859
+ `file-deletions`, `copy-button`, and `actions`.
10860
+
10861
+ ## `lyra-image-viewer`
10862
+
10863
+ A full pan/zoom raster-image viewer with labeled region highlights and opt-in region annotation, the
10864
+ landing surface for `region`-anchored citations. Distinct from `<lyra-svg-viewer>` (rendered SVG
10865
+ documents) and `<lyra-image-comparer>` (before/after slotted surfaces). Adopts `DocumentAnchorTarget`
10866
+ with `anchorKinds: ['region']` only — no text selection is bound.
10867
+
10868
+ **Properties:** `src: string = ''`, `name: string = ''`, `alt?: string`, `fit: 'contain' | 'width' |
10869
+ 'actual' = 'contain'` (reflected), `zoom: number = 1` (reflected), `rotation: 0 | 90 | 180 | 270 = 0`
10870
+ (reflected), and `annotatable: boolean = false` (reflected).
10871
+
10872
+ **Methods:** `rotate()` advances `rotation` by 90°. `zoomIn()`, `zoomOut()`, and `resetZoom()` adjust
10873
+ the embedded zoomable-frame's zoom.
10874
+
10875
+ **Events:** `lyra-load` (`detail: { naturalWidth, naturalHeight }`), `lyra-zoom-change` (`detail: {
10876
+ zoom }`), `lyra-rotation-change` (`detail: { rotation }`), `lyra-fit-change` (`detail: { fit }`),
10877
+ `lyra-highlight-activate` (`detail: { id }`), `lyra-annotation-create` (`detail: { anchor }`, kind
10878
+ `'region'`), `lyra-anchor-result` (`detail: { found }`), and `lyra-render-error` (`detail: { error
10879
+ }`).
10880
+
10881
+ **CSS parts:** `base`, `toolbar`, `fit-control`, `rotate-button`, `annotate-toggle`, `frame` (the
10882
+ embedded `lyra-zoomable-frame`), `image-wrapper`, `image`, `highlight-layer`, `highlight` (carries
10883
+ `data-tone`/`data-active`), `highlight-label`, `annotation-box`, and `error`.
10884
+
10885
+ ## `lyra-transcript-feed`
10886
+
10887
+ Live captions for an in-progress voice session: speaker-grouped entries, interim-vs-final styling
10888
+ with in-place upgrades keyed by `id`, and a stick-to-bottom auto-scroll with release, the same
10889
+ `follow`/`lyra-follow-change` contract `<lyra-terminal>` uses. Live captions only — recorded-media
10890
+ transcript sync is a separate concern.
10891
+
10892
+ **Properties:** `entries: LyraTranscriptEntry[] = []` (attribute: false), `follow: boolean = true`
10893
+ (reflected), `showTimestamps: boolean = false` (attribute `show-timestamps`), `formatTimestamp?:
10894
+ (epochMs: number) => string` (attribute: false), `maxRenderedEntries: number = 0` (attribute
10895
+ `max-rendered-entries`), `label: string = ''` — accessible name for the `role="log"` region
10896
+ (default: the localized `transcriptFeedLabel`), and `accessibleLabel: string | null = null`
10897
+ (attribute `aria-label`) — overrides the log's computed accessible name, winning over `label` and
10898
+ the localized default; attribute-reflects from a host-level `aria-label`.
10899
+
10900
+ **Methods:** `scrollToBottom()` re-engages `follow` and scrolls to the latest entry.
10901
+
10902
+ **Slots:** `empty` — custom empty state (default: the localized "No transcript yet").
10903
+
10904
+ **Events:** `lyra-follow-change` — `detail: { following }`, fires on every `follow` transition.
10905
+
10906
+ **CSS parts:** `base` (the scroll container), `log` (the `role="log"` region wrapping final entries
10907
+ only), `entry`, `speaker` (omitted for a row repeating the previous row's speaker), `text`
10908
+ (`dir="auto"`), `timestamp` (only while `show-timestamps`), `interim` (present alongside `entry` on
10909
+ an interim row), `jump-button` (shown only while `follow` is `false`), and `empty`.
10910
+
10911
+ ## `lyra-av-player`
10912
+
10913
+ An audio/video player built on a native `<audio>`/`<video>` element, plus a cue transcript synced to
10914
+ `currentTime`, `time-range` anchor/highlight support, an optional dependency-free waveform (peaks
10915
+ in, no in-component decoding), and playback-rate control. Owns recorded-media transcript sync —
10916
+ distinct from `<lyra-transcript-feed>` (live captions for an in-progress voice session) and
10917
+ `<lyra-playback>` (an index stepper, no media). Adopts `DocumentAnchorTarget` with
10918
+ `anchorKinds: ['time-range']` only — no text selection is bound. The transcript virtualizes through
10919
+ `<lyra-virtual-list>` the same way `lyra-pdf-viewer` virtualizes pages.
10920
+
10921
+ **Properties:** `src: string = ''`, `name: string = ''`, `kind?: 'audio' | 'video'` (attribute:
10922
+ false auto-detection override), `mimeType: string = ''` (attribute `mime-type`), `poster: string =
10923
+ ''`, `loop: boolean = false`, `muted: boolean = false`, `preload: 'none' | 'metadata' | 'auto' =
10924
+ 'metadata'`, `playbackRate: number = 1` (attribute `playback-rate`, reflected), `rates: number[] =
10925
+ [0.75, 1, 1.25, 1.5, 2]` (attribute: false), `cues: LyraAvCue[] = []` (attribute: false), `peaks:
10926
+ number[] = []` (attribute: false), and `tracks: LyraAvTrack[] = []` (attribute: false).
10927
+ `LyraAvCue = { id, start, end?, text, speaker? }`; `LyraAvTrack = { src, kind: 'subtitles' |
10928
+ 'captions' | 'descriptions', srclang, label, default? }`.
10929
+
10930
+ **Methods:** `play()`, `pause()`, and `toggle()` proxy the native media element. `seek(seconds)`
10931
+ sets `currentTime` and forces an immediate `lyra-time-change`. `search(query)` resolves the match
10932
+ count; `searchNext()`/`searchPrevious()` wrap; `clearSearch()` resets.
10933
+
10934
+ **Events:** `lyra-play`, `lyra-pause`, `lyra-load` (`detail: { duration, kind }`), `lyra-time-change`
10935
+ (`detail: { currentTime }`, throttled to at most 4/s while playing plus one extra per `seek()`),
10936
+ `lyra-rate-change` (`detail: { rate }`), `lyra-cue-change` (`detail: { id }`, `id` is `null` when no
10937
+ cue is active), `lyra-highlight-activate` (`detail: { id }`), `lyra-anchor-result` (`detail: {
10938
+ found }`), `lyra-search-change` (`detail: { query, matchCount, activeIndex }`), and
10939
+ `lyra-render-error` (`detail: { error }`).
10940
+
10941
+ **CSS parts:** `base`, `media` (the native `<audio>`/`<video>` element), `toolbar`, `rate-select`,
10942
+ `timeline` (click-to-seek and arrow-key seeking), `timeline-marker` (one per `time-range` highlight;
10943
+ `data-tone`, `data-active`), `transcript` (the `<lyra-virtual-list>` itself), `cue` (`aria-current`,
10944
+ `data-match`, `data-active-match`), `cue-time`, `cue-speaker`, `cue-text`, and `error`.
10945
+
10946
+ ## `lyra-test-results`
10947
+
10948
+ A pass/fail suite summary with per-status counts, status filter toggles, and per-test rows whose
10949
+ failures auto-expand by default and can host rich slotted detail (e.g. a diff or code block)
10950
+ alongside the plain failure message.
10951
+
10952
+ **Properties:** `suites: TestSuiteResult[] = []` (attribute: false), `statusFilter: TestStatus[] =
10953
+ []` (attribute: false), and `autoExpandFailures: boolean = true` (attribute
10954
+ `auto-expand-failures`).
10955
+
10956
+ **Slots:** `detail-{testId}` — rich failure detail for that test, rendered after its plain message
10957
+ text once the row is expanded.
10958
+
10959
+ **Events:** `lyra-test-select` (`detail: { suiteId, testId }`, a test row's name was activated),
10960
+ `lyra-filter-change` (`detail: { statuses }`, the status-set filter changed), and `lyra-toggle`
10961
+ (`detail: { id, expanded }`, a row's failure detail was expanded/collapsed).
10962
+
10963
+ **CSS parts:** `base`, `summary` (the status-count strip), `count` (carries `data-status`), `filter`,
10964
+ `filter-toggle` (carries `data-status`/`aria-pressed`), `suite`, `suite-header`, `test` (carries
10965
+ `data-status`), `test-status`, `test-name`, `test-duration`, `test-expand-toggle`, `failure`
10966
+ (hidden while collapsed), and `failure-message`.
10967
+
10968
+ ## `lyra-env-list`
10969
+
10970
+ A masked key/value list for environment variables and secrets, with per-row reveal and copy.
10971
+ Masking is presentational, not a security boundary: the real value sits in a DOM property
10972
+ regardless of mask state.
10973
+
10974
+ **Properties:** `entries: EnvEntry[] = []` (attribute: false), `revealable: boolean = true`
10975
+ (reflected), `copyable: boolean = true` (reflected), and `label: string = ''`.
10976
+
10977
+ **Events:** `lyra-reveal-change` (`detail: { name, revealed }`) and `lyra-copy` (`detail: { text }`,
10978
+ the real unmasked value).
10979
+
10980
+ **CSS parts:** `base` (the `<dl>` root), `name` (the `<dt>` text), `value-cell` (the `<dd>` wrapping
10981
+ an entry's value text and buttons), `value` (carries `data-masked`), `reveal-button`, and
10982
+ `copy-button`.
10983
+
10984
+ ## `lyra-handoff-divider`
10985
+
10986
+ A labeled semantic separator marking control transfer between agents in a transcript ("Transferred
10987
+ to Research Agent"), with an optional agent avatar. Purely presentational: no events, no
10988
+ interactivity, no restore semantics. The computed label is announced once, on first connect,
10989
+ through an internal `<lyra-live-region>`.
10990
+
10991
+ **Properties:** `agent: string = ''`, `fromAgent: string = ''` (attribute `from-agent`), and `label:
10992
+ string = ''`.
10993
+
10994
+ **Slots:** `avatar` — the incoming agent's `<lyra-avatar>` (or icon), hidden entirely while empty.
10995
+
10996
+ **CSS parts:** `base` (the separator root, `role="separator"`), `line` (each of the two flanking
10997
+ rules), `chip` (the visual `aria-hidden` chip wrapping the avatar and label), `avatar` (wrapper
10998
+ around the `avatar` slot, only shown while the slot has content), and `label`.
10999
+
11000
+ ## `lyra-chat-viewport`
11001
+
11002
+ The transcript scroll container: owns stick-to-bottom behavior while an answer streams, the "jump to
11003
+ latest" pill, and the unread divider. Two supported content shapes, auto-detected: ordinary element
11004
+ children (typically `lyra-chat-message`s — *slotted mode*), or exactly one `lyra-virtual-list`
11005
+ (*virtual mode*, detected via `instanceof`). In virtual mode this component defers all scrolling to
11006
+ the slotted list's own `scrollToIndex()`. Follow/release state machine: while `follow` is engaged,
11007
+ content growth re-scrolls to the end; release happens only on a user-intent gesture (wheel,
11008
+ touchmove, scrollbar-drag, or PageUp/ArrowUp/Home while the log region has focus) that leaves the
11009
+ view more than `bottomThreshold` from the end — a scroll caused by this component's own programmatic
11010
+ scrolling, or by a layout shift, never releases it. Reaching the bottom again by any means re-engages
11011
+ `follow`.
11012
+
11013
+ **Properties:** `follow: boolean = true` (reflected) — component-managed stick-to-bottom state,
11014
+ host-writable: setting `true` scrolls to the end and re-engages following, setting `false` releases
11015
+ it. `bottomThreshold: number = 24` (attribute `bottom-threshold`) — px distance from the end still
11016
+ counted as "at bottom." `unreadStartIndex: number | null = null` (attribute `unread-start-index`) —
11017
+ index of the first unread item (element-child index in slotted mode, `items` index in virtual mode);
11018
+ `null` disables both the divider and the pill's unread count. `label: string = ''` — accessible name
11019
+ for the log region, defaults to the localized `chatViewportLabel`. `accessibleLabel: string | null =
11020
+ null` (attribute `aria-label`) — host `aria-label`, forwarded to the internal `role="log"` element
11021
+ (an `aria-label` left on the host itself names nothing, since the log role lives inside the shadow
11022
+ root); wins over `label` and the localized default.
11023
+
11024
+ **Methods:** `scrollToBottom(options?)` — scrolls to the end and re-engages `follow`; default
11025
+ `smooth`, forced to `auto` under `prefers-reduced-motion`. `scrollToUnread(options?)` — scrolls the
11026
+ unread divider to the top of the view, resolving `false` when `unreadStartIndex` is `null`/out of
11027
+ range; does not re-engage `follow`.
11028
+
11029
+ **Events:** `lyra-follow-change` — `detail: { following }`, fired whenever `follow` flips (user
11030
+ scroll-up release, or reaching the bottom again). Never fired for the initial mount state.
11031
+
11032
+ **Slots:** default — the transcript: ordinary element children, or exactly one `lyra-virtual-list`.
11033
+
11034
+ **CSS parts:** `base` (the positioning root), `scroll` (the scroll container, `role="log"`,
11035
+ `tabindex="0"`; in virtual mode it stops scrolling itself but keeps the role), `content` (the
11036
+ slotted-content wrapper the growth observers watch), `jump-pill` (the built-in jump-to-latest button,
11037
+ absent while `follow` is engaged), `unread-divider` (the "New messages" separator, slotted mode
11038
+ only).
11039
+
11040
+ Renders no messages and computes no unread state itself — the host supplies `unreadStartIndex`; no
11041
+ virtualization of its own (`lyra-virtual-list`); not a generic overflow surface (`lyra-scroller`); no
11042
+ message semantics (`lyra-chat-message`).
11043
+
11044
+ ```html
11045
+ <lyra-chat-viewport unread-start-index="12" @lyra-follow-change=${(e) => console.log(e.detail.following)}>
11046
+ <lyra-chat-message role="user">…</lyra-chat-message>
11047
+ <lyra-chat-message role="assistant" status="streaming">
11048
+ <lyra-streaming-text streaming .content=${partial}></lyra-streaming-text>
11049
+ </lyra-chat-message>
11050
+ </lyra-chat-viewport>
11051
+ <lyra-chat-composer status="streaming"></lyra-chat-composer>
11052
+ ```
11053
+
11054
+ ## `lyra-suggestion-chips`
11055
+
11056
+ Starter prompts (empty thread) and follow-up suggestions (after a response) as a horizontally
11057
+ scrollable chip row; activation hands the prompt to the host, which decides whether to compose it
11058
+ into an input or send it directly. Never writes into a composer or sends anything itself.
11059
+ Streaming-friendly: chips render through a keyed `repeat()` on `id`, so replacing follow-ups
11060
+ mid-conversation preserves focus on any chip whose `id` survives.
11061
+
11062
+ **Properties:** `suggestions: ChatSuggestion[] = []` (attribute: false, each `{ id, label, detail? }`
11063
+ — `detail` is an optional secondary line). Empty renders nothing at all. `wrap: boolean = false`
11064
+ (reflected) — wraps into multiple rows instead of a single horizontally scrollable line. `label:
11065
+ string = ''` — accessible name for the group, defaults to the localized `suggestionsLabel`.
11066
+
11067
+ **Events:** `lyra-suggestion-select` — `detail: { id, label }`.
11068
+
11069
+ **CSS parts:** `base` (the labeled group), `chip` (each suggestion button), `chip-label` (the primary
11070
+ text), `chip-detail` (the secondary line, only rendered when `detail` is set).
11071
+
11072
+ Keyboard: roving tabindex across chips; ArrowLeft/ArrowRight (direction-aware) plus Home/End;
11073
+ Enter/Space activate. Renders inside an internal `lyra-scroller` (`orientation="horizontal"`,
11074
+ `hide-scrollbar`) unless `wrap` is set.
11075
+
11076
+ ```html
11077
+ <lyra-suggestion-chips .suggestions=${followUps}
11078
+ @lyra-suggestion-select=${(e) => (composer.value = e.detail.label)}></lyra-suggestion-chips>
11079
+ <lyra-chat-composer></lyra-chat-composer>
11080
+ ```
11081
+
11082
+ ## `lyra-thread-list`
11083
+
11084
+ The conversation sidebar: a grouped, searchable list of chat sessions with pin/archive/delete/rename
11085
+ affordances. *Data mode* (non-empty `threads`, or empty `threads` with nothing slotted) renders every
11086
+ row as a `lyra-conversation-item` inside an internal `lyra-virtual-list` — virtualized by
11087
+ construction, scroll position and per-row state survive a `threads` replacement; zero rows renders
11088
+ the built-in empty state. *Slotted mode* (empty `threads` *and* real slotted content) renders
11089
+ host-supplied `lyra-conversation-item`s from the default slot as-is: no grouping, virtualization, or
11090
+ row actions in that mode. No thread CRUD or persistence — every mutation
11091
+ (`lyra-thread-pin`/`-archive`/`-delete`/`-rename`) is a controlled event carrying the *requested* new
11092
+ state; the host mutates `threads`.
11093
+
11094
+ **Properties:** `threads: ChatThread[] = []` (attribute: false, each `{ id, title, excerpt?,
11095
+ timestamp?, pinned?, archived? }`). `activeId: string = ''` (attribute `active-id`) — data mode:
11096
+ marks the matching row `active`/`aria-current` and scrolls it into view. `searchable: boolean =
11097
+ false` (reflected) — shows the built-in search field. `filter?: (thread, query) => boolean`
11098
+ (attribute: false) — overrides the default case-insensitive `title` + `excerpt` substring match.
11099
+ `grouping: 'date' | 'none' = 'date'` — data mode: bucket rows under localized date headers
11100
+ (Pinned/Today/Yesterday/Previous 7 days/Previous 30 days/one bucket per month/Archived), or a flat
11101
+ list. `rowActions: ThreadRowAction[] = []` (attribute: false, each `'pin' | 'archive' | 'delete'`) —
11102
+ data mode only: built-in icon buttons rendered into each row's `actions` slot. `showArchived: boolean
11103
+ = false` (attribute `show-archived`, reflected) — data mode: include `archived` threads (in their own
11104
+ trailing group). `editable: boolean = true` (reflected) — forwarded to each data-mode row's inline
11105
+ rename. `label: string = ''` — accessible name for the list region, defaults to the localized
11106
+ `threadListLabel`.
11107
+
11108
+ **Slots:** default — slotted mode only: host-supplied `lyra-conversation-item`s, rendered in order.
11109
+ `empty` — replaces the built-in empty state.
11110
+
11111
+ **Events:** (data mode; slotted mode only ever fires `lyra-filter-change`) `lyra-select` (`detail: {
11112
+ id }`), `lyra-thread-pin` (`detail: { id, pinned }` — the requested new state), `lyra-thread-archive`
11113
+ (`detail: { id, archived }`), `lyra-thread-delete` (`detail: { id }`, no built-in confirmation),
11114
+ `lyra-thread-rename` (`detail: { id, title }`, re-emitted from the row's `lyra-rename`),
11115
+ `lyra-filter-change` (`detail: { text, matchCount }`).
11116
+
11117
+ **CSS parts:** `base`, `search`/`search-input` (the search field wrapper and `<input
11118
+ type="search">`), `list` (the list region), `empty`, `row-action` (a built-in pin/archive/delete icon
11119
+ button), `pin-glyph` (the small pin indicator on a pinned row), `group-header`/`row` (exported from
11120
+ the internal `lyra-virtual-list`).
11121
+
11122
+ ```html
11123
+ <lyra-thread-list
11124
+ searchable
11125
+ .threads=${threads}
11126
+ active-id=${activeThreadId}
11127
+ .rowActions=${['pin', 'archive', 'delete']}
11128
+ @lyra-select=${(e) => openThread(e.detail.id)}
11129
+ ></lyra-thread-list>
11130
+ ```
11131
+
11132
+ Composed with `lyra-split` (or `lyra-app-rail` + `lyra-responsive-panel`): thread-list in the start
11133
+ pane driving `activeId`, `lyra-chat-viewport` + `lyra-chat-composer` in the main pane.
11134
+
11135
+ ## `lyra-confirm-bar`
11136
+
11137
+ An inline, non-modal approve/deny block for one proposed action — the in-flow sibling of
11138
+ `lyra-tool-approval-dialog` for confirmations that should sit in the transcript instead of hijacking
11139
+ focus. Same `lyra-approve`/`lyra-deny` event shapes as the dialog, and the same
11140
+ `toolApprovalHeading`/`toolApprovalArgsLabel`/`deny`/`approve` localization keys, so the two always
11141
+ translate in lockstep. Non-modal by contract: no focus trap, no scroll lock, no Escape/backdrop
11142
+ semantics, and it never steals focus when it appears in the transcript. DOM and tab order put Deny
11143
+ before Approve. On activation, focus moves synchronously to `[part="status"]` (an always-rendered,
11144
+ `tabindex="-1"` element) before the Deny/Approve buttons unmount.
11145
+
11146
+ **Properties:** `toolName: string = ''` (attribute `tool-name`) — drives the default heading through
11147
+ the existing `toolApprovalHeading`/`toolApprovalGenericTool` dialog keys. `heading: string = ''` —
11148
+ free-form heading override for non-tool proposals; wins over `toolName`. `args: unknown = undefined`
11149
+ (attribute: false) — shown read-only inside a collapsed `lyra-details` + `lyra-json-viewer` when
11150
+ defined. `decision: 'approved' | 'denied' | null = null` (reflected) — decided state, set by the
11151
+ component on activation and host-writable (an externally-resolved decision renders identically but
11152
+ emits nothing). `tone: 'neutral' | 'danger' = 'neutral'` (reflected).
11153
+
11154
+ **Slots:** default — supplementary body content between the heading and the actions (e.g. a
11155
+ `lyra-diff-view`). `footer` — extra content at the start of the action row.
11156
+
11157
+ **Events:** `lyra-approve` (`detail: { args }` — the `args` prop as-is, identical shape to
11158
+ `lyra-tool-approval-dialog`), `lyra-deny` (no detail, identical to the dialog).
11159
+
11160
+ **CSS parts:** `base` (`role="group"`), `heading`/`tool-name`, `body`, `args` (the
11161
+ details/json-viewer wrapper, only rendered when `args` is defined), `footer`, `deny-button`,
11162
+ `approve-button` (named identically to the dialog's parts), `status` (the decided-state text, always
11163
+ present in the DOM as a focus landing spot).
11164
+
11165
+ ```html
11166
+ <lyra-tool-call-chip status="pending"></lyra-tool-call-chip>
11167
+ <lyra-confirm-bar tool-name="run_shell" .args=${args}
11168
+ @lyra-approve=${(e) => run(e.detail.args)} @lyra-deny=${() => cancel()}
11169
+ ></lyra-confirm-bar>
11170
+ ```
11171
+
11172
+ ## `lyra-checkpoint`
11173
+
11174
+ An inline conversation restore point: a labeled marker between messages whose Restore affordance
11175
+ confirms inline, then hands the host a `lyra-restore` event. This component persists and restores
11176
+ nothing itself — host state in, events out. Not a handoff or plain rule
11177
+ (`lyra-handoff-divider`/`lyra-divider`); not branch navigation across regenerated variants
11178
+ (`lyra-branch-picker`); not recorded-run playback (`lyra-playback`).
11179
+
11180
+ **Properties:** `checkpointId: string = ''` (attribute `checkpoint-id`) — opaque id echoed in the
11181
+ `lyra-restore` event detail. `label: string = ''` — checkpoint name; the localized `checkpointLabel`
11182
+ fallback renders while empty. `timestamp?: Date | string` (attribute: false) — optional creation
11183
+ time, rendered as `<time datetime>`, default `hour:minute` in `effectiveLocale`; invalid strings are
11184
+ treated as unset. `formatTimestamp?: (date: Date) => string` (attribute: false) — overrides the
11185
+ default rendering. `restorable: boolean = true` — when `false`, renders a plain marker with no
11186
+ button. `confirmRestore: boolean = true` (attribute `confirm-restore`) — gates the event behind an
11187
+ inline confirm step; a string-aware converter parses `confirm-restore="false"` correctly from plain
11188
+ HTML. `restoring: boolean = false` (reflected) — host-set busy state: the Restore button becomes
11189
+ `aria-disabled="true"` with a spinner beside the localized "Restoring…" text.
11190
+
11191
+ **Slots:** default — optional supplemental content under the marker row (e.g. what changed since
11192
+ this point).
11193
+
11194
+ **Events:** `lyra-restore` — `detail: { checkpointId, label }`; fired on Restore activation, after
11195
+ the inline confirm when `confirmRestore` is on. Not cancelable.
11196
+
11197
+ **CSS parts:** `base` (`role="group"`), `line` (each of the two flanking rules), `icon` (bookmark
11198
+ glyph), `label`, `timestamp`, `restore-button` (only while `restorable`), `confirm-group`,
11199
+ `confirm-prompt`, `confirm-button`, `cancel-button`.
11200
+
11201
+ **Themeable custom properties:** `--lyra-checkpoint-spin-duration` (default `1s`) — duration of one
11202
+ restoring-spinner rotation; stopped under reduced motion.
11203
+
11204
+ ```html
11205
+ <lyra-checkpoint checkpoint-id="ck_18" label="Before refactor" .timestamp=${t}
11206
+ @lyra-restore=${(e) => restoreTo(e.detail.checkpointId)}></lyra-checkpoint>
11207
+ ```
11208
+
11209
+ ## `lyra-usage-badge`
11210
+
11211
+ Compact, static resource strip for one message or run — tokens in/out, cost, latency — with a
11212
+ hover/focus tooltip breakdown. Purely formatting: computes no counts, rates, or prices; every segment
11213
+ is independently optional, and with nothing set, nothing renders at all (not even a focusable shell).
11214
+ The tooltip reuses `lyra-tool-call-chip`'s hover/focus/Escape/`aria-describedby` contract wholesale.
11215
+ Not `lyra-context-meter` (occupancy of a fixed capacity); not `lyra-generation-status` (live, with a
11216
+ Stop button) — this is static after the fact.
11217
+
11218
+ **Properties:** `tokensIn?: number` (attribute `tokens-in`) — input tokens, normalized to a
11219
+ non-negative integer, locale-formatted; segment omitted while unset/non-finite. `tokensOut?: number`
11220
+ (attribute `tokens-out`) — same rules. `costText: string = ''` (attribute `cost-text`) —
11221
+ pre-formatted cost (e.g. `"$0.012"`), rendered verbatim. `latencyMs?: number` (attribute
11222
+ `latency-ms`) — formatted with the shared duration algorithm (`820 -> "820ms"`, `1500 -> "1.5s"`).
11223
+ `compact: boolean = false` — token counts render via `Intl.NumberFormat` `notation: 'compact'`; the
11224
+ tooltip always shows full grouped figures.
11225
+
11226
+ **Slots:** default — extra rows appended below the built-in tooltip breakdown (e.g. cache-read
11227
+ tokens); the visible strip itself is prop-driven only.
11228
+
11229
+ **CSS parts:** `base` (a focusable non-button `role="group"`, only rendered while at least one
11230
+ segment or the default slot has content), `tokens-in`, `tokens-out`, `cost`, `latency`, `tooltip`.
11231
+
11232
+ ```html
11233
+ <lyra-chat-message role="assistant" status="sent">
11234
+ <lyra-usage-badge slot="badges" tokens-in="1204" tokens-out="386"
11235
+ cost-text="$0.012" latency-ms="2350"></lyra-usage-badge>
11236
+ <lyra-markdown .content=${answer}></lyra-markdown>
11237
+ </lyra-chat-message>
11238
+ ```
11239
+
11240
+ ## `lyra-browser-frame`
11241
+
11242
+ Presentational "agent computer" viewport: a screenshot/frame stream (or slotted live media), a
11243
+ read-only URL display, action-ping overlays, and take-over/stop affordances. No automation transport
11244
+ (no CDP/WebRTC/WebSocket) and no input relay — take-over is an event; the host swaps in its own
11245
+ interactive element (e.g. an iframe). No replay scrubber (compose `lyra-playback` driving `frame-src`
11246
+ from a screenshot array); no console/network drawers (compose `lyra-terminal`/`lyra-json-viewer`); no
11247
+ pan/zoom of the frame content (slot the image/video inside a `lyra-zoomable-frame` instead, though
11248
+ the pings overlay assumes the unzoomed content box in that composition).
11249
+
11250
+ **Properties:** `frameSrc: string = ''` (attribute `frame-src`) — image/MJPEG stream URL rendered as
11251
+ an `<img>` (safe-URL-gated via `safeMediaSrc`); ignored once the default slot has content. `url:
11252
+ string = ''` — address shown read-only in the toolbar (`dir="ltr"`, truncating, full value in
11253
+ `title`). `status: 'idle' | 'connecting' | 'streaming' | 'stalled' = 'idle'` (reflected). `controller:
11254
+ 'agent' | 'user' = 'agent'` (reflected) — who is driving; switches the take-over button's label.
11255
+ `pings: BrowserPing[] = []` (attribute: false, each `{ id, x, y, kind: 'click' | 'type' | 'scroll' |
11256
+ 'move' }` — `x`/`y` are percent (0–100) of the frame's `object-fit: contain` content box,
11257
+ letterboxing-aware). `controls: boolean = true` — render the built-in take-over/stop buttons.
11258
+
11259
+ **Slots:** default — host-owned live element (e.g. `<video>` or an interactive `<iframe>`), replacing
11260
+ the `frame-src` image. `actions` — extra toolbar controls.
11261
+
11262
+ **Events:** `lyra-take-over` — `detail: { controller }`, the *requested* controller (`'user'` when
11263
+ "Take over" is pressed, `'agent'` when "Hand back" is). `lyra-stop` — stop the agent's browser
11264
+ session, no detail.
11265
+
11266
+ **CSS parts:** `base` (`role="group"`), `toolbar`, `url`, `status` (`role="status"`),
11267
+ `controller-badge`, `actions`, `take-over-button`, `stop-button`, `viewport`, `frame` (the
11268
+ `frame-src` `<img>`, absent once the default slot is populated), `ping` (one action-ping marker,
11269
+ carries `data-kind`).
11270
+
11271
+ **Themeable custom properties:** `--lyra-browser-frame-aspect-ratio` (default `16 / 9`) — the
11272
+ viewport's aspect ratio.
11273
+
11274
+ ```html
11275
+ <lyra-browser-frame status="streaming" url="https://example.com" .pings=${pings}
11276
+ @lyra-take-over=${(e) => setController(e.detail.controller)} @lyra-stop=${() => stopSession()}
11277
+ ></lyra-browser-frame>
11278
+ ```
11279
+
11280
+ ## `lyra-artifact-panel`
11281
+
11282
+ Shell around one agent-generated artifact: a title/kind header, a preview↔code toggle, version
11283
+ navigation with restore, a streaming indicator, and built-in copy/download actions. Renders none of
11284
+ the artifact itself — content is slotted. No content rendering of its own (slots own it), no
11285
+ dialog/dock chrome (compose `lyra-dialog`/`lyra-dock-panel`/`lyra-split`), no version storage or
11286
+ diffing (host state; diffs via `lyra-diff-view`), no code editing (`lyra-code-editor`).
11287
+
11288
+ **Properties:** `label: string = ''` — the artifact's title, shown in the header. `kind: string = ''`
11289
+ — a short kind label (e.g. `document`, `code`), shown as a badge next to `label`. `view: 'preview' |
11290
+ 'code' = 'preview'` (reflected) — which slot is currently visible. `versions: ArtifactVersion[] = []`
11291
+ (attribute: false, each `{ id, label? }`) — the artifact's version history, oldest first; the last
11292
+ entry is the latest version. `activeVersionId: string | null = null` (attribute
11293
+ `active-version-id`) — the currently viewed version's id, or `null` for "the latest version."
11294
+ `streaming: boolean = false` (reflected) — whether the artifact is still being generated; sets
11295
+ `aria-busy` on the body and shows a text indicator (not animated, so it stays legible under reduced
11296
+ motion). `copyText: string = ''` (attribute `copy-text`) — the text copied to the clipboard by the
11297
+ copy button; empty hides the button. `downloadSrc: string = ''` (attribute `download-src`) — the
11298
+ download URL, sanitized through `safeMediaSrc()`; empty hides the button. `downloadName: string =
11299
+ ''` (attribute `download-name`) — the suggested filename reported in the `lyra-download` event
11300
+ detail.
11301
+
11302
+ **Slots:** default — preview-view content (markdown/html-viewer/browser-frame/image). `code` —
11303
+ code-view content (typically a `lyra-code-block`); the preview/code toggle only renders once this
11304
+ slot has assigned content. `actions` — extra header controls, rendered between the version
11305
+ navigation and the built-in copy/download buttons.
11306
+
11307
+ **Events:** `lyra-view-change` (`detail: { view }`), `lyra-version-change` (`detail: { versionId }`,
11308
+ fired when the previous/next navigation moves to a different version), `lyra-restore` (`detail: {
11309
+ versionId }`, fired by the restore-this-version button; mutates nothing itself), `lyra-copy`
11310
+ (`detail: { text }`, after a best-effort clipboard write), `lyra-download` (`detail: { filename,
11311
+ src? }`, with the sanitized download URL).
11312
+
11313
+ **CSS parts:** `base`, `header`, `label`, `kind`, `view-toggle` (rendered only once the `code` slot
11314
+ has content), `view-button` (carries `data-view="preview"` or `data-view="code"`), `version-nav`
11315
+ (rendered only once `versions` is non-empty), `version-previous`, `version-next`, `version-position`
11316
+ (the "Version N of M" text), `restore-button` (rendered only while the active version isn't the
11317
+ latest), `actions`, `copy-button` (rendered only while `copyText` is non-empty), `download-button`
11318
+ (rendered only while `downloadSrc` is non-empty), `body`, `streaming-indicator` (rendered only while
11319
+ `streaming`).
11320
+
11321
+ ```html
11322
+ <lyra-artifact-panel label="report.md" kind="document" .versions=${versions}
11323
+ @lyra-restore=${(e) => restoreVersion(e.detail.versionId)}>
11324
+ <lyra-markdown .content=${markdown}></lyra-markdown>
11325
+ <lyra-code-block slot="code" language="markdown" .code=${markdown}></lyra-code-block>
11326
+ </lyra-artifact-panel>
11327
+ ```
11328
+
11329
+ ## `lyra-widget-renderer`
11330
+
11331
+ Renders an agent-streamed declarative JSON widget tree through an allowlisted `type -> lyra tag`
11332
+ registry: safe generative UI with exactly one action event out. A mapped node's real element is
11333
+ created via `document.createElement()` with every prop assigned as a plain JS property (never
11334
+ `setAttribute`, never `innerHTML`), and reused by key across a re-resolve so a mapped widget's own
11335
+ internal state (an open `<details>`, focus, scroll position) survives a streamed `tree` update.
11336
+ Built-in `row`/`col`/`text` structural nodes render through ordinary nested templates instead. Not a
11337
+ form runtime (no input/select/form types in the default registry), no expression language or
11338
+ data-binding, no remote widget/schema fetching, and it never renders arbitrary HTML or navigates (no
11339
+ `href` props are allowlisted anywhere).
11340
+
11341
+ **Exported types:** `WidgetNode { type: string; id?: string; props?: Record<string, unknown>;
11342
+ children?: (WidgetNode | string)[]; slot?: string; actionId?: string; payload?: unknown }` — `id` is
11343
+ a stable reconciliation key (falling back to a structural path), `slot` is honored only when the
11344
+ parent type allowlists it, `actionId` arms the type's declared action trigger, and `payload` is
11345
+ echoed back in `lyra-widget-action`.
11346
+
11347
+ **Properties:** `tree: WidgetNode | null = null` (property only) — the declarative widget tree to
11348
+ render; `null` renders an empty base. `registry?: WidgetTypeRegistry` (attribute: false) — a
11349
+ per-instance override of the module-level default registry.
11350
+
11351
+ **Registry module (`widget-renderer/registry.js`):** `registerWidgetType(type, def)` registers (or
11352
+ overwrites) a type in the default registry; `def: WidgetTypeDefinition { tag?: string; props?:
11353
+ Record<string, 'string' | 'number' | 'boolean'>; forcedProps?: Record<string, unknown>; slots?:
11354
+ string[]; action?: { event: string } }` — `tag` is resolved prefix-aware, `props` is a prop allowlist
11355
+ (a prop absent here, or whose runtime type doesn't match, is silently skipped — never assigned),
11356
+ `forcedProps` always apply and are never overridable by `WidgetNode.props`, `slots` allowlists child
11357
+ `slot` names (a disallowed one renders unslotted rather than being dropped), and `action.event` is
11358
+ the native/custom DOM event that arms `lyra-widget-action` when a node also sets `actionId`.
11359
+ `getDefaultWidgetTypeRegistry()` returns the module-level registry `registerWidgetType()` writes to.
11360
+
11361
+ **Default registry** (populated by the side-effect entry's `registerDefaultWidgetTypes()`): `text`
11362
+ (plain text node), `row`/`col` (internal flex wrappers; props `gap: 's'|'m'|'l'`, `align:
11363
+ 'start'|'center'|'end'|'stretch'`, `justify: 'start'|'center'|'end'|'between'`), `card` →
11364
+ `lyra-card` (`appearance`), `badge` → `lyra-badge` (`variant`), `button` → `lyra-button` (`variant`,
11365
+ `appearance`, `size`, `disabled`, `loading`; action: `click`), `stat` → `lyra-stat` (`label`,
11366
+ `value`, `unit`, `variant`, `caption`, `sub`), `result-card` → `lyra-result-card` (`title`),
11367
+ `result-field` → `lyra-result-field` (`label`, `value`), `markdown` → `lyra-markdown` (`content`;
11368
+ forced `{ sanitize: true }`), `image` → `lyra-media-card` (`src`, `alt`, `filename`; forced `{ kind:
11369
+ 'image' }`).
11370
+
11371
+ **Events:** `lyra-widget-action` — `detail: { actionId, payload }`, the single bubbling action
11372
+ channel. `lyra-render-error` — `detail: { error }`, the root value was structurally unusable
11373
+ (non-object, or the depth/size caps made it empty).
11374
+
11375
+ **CSS parts:** `base` (the root wrapper, `display: contents`), `row`, `col`, `text` (built-in
11376
+ structural nodes only — a mapped lyra component exposes its own parts instead).
11377
+
11378
+ Caps: depth 32, 5,000 nodes — excess is skipped with a deduped `console.warn` per type/prop per
11379
+ instance. Reconciliation is keyed by `id ?? structural path`, so a streamed re-send patches in
11380
+ place and user state (an open `<details>`, focus, scroll) survives.
11381
+
11382
+ ```ts
11383
+ registerWidgetType('sparkline', { tag: tag('sparkline'), props: { data: 'string' } });
11384
+ ```
11385
+ ```html
11386
+ <lyra-widget-renderer .tree=${msg.widget}
11387
+ @lyra-widget-action=${(e) => sendToAgent(e.detail.actionId, e.detail.payload)}
11388
+ ></lyra-widget-renderer>
11389
+ ```
11390
+
11391
+ **Optional peer deps:** none new — the default-registry entry directly imports the eight mapped
11392
+ components (`markdown` keeps its own `marked`/`dompurify` optional-peer fallback). A host wanting a
11393
+ leaner dependency graph registers a custom registry (via the `registry` property) and imports only
11394
+ the components it maps.
11395
+
11396
+ ## `lyra-voice-picker`
11397
+
11398
+ A TTS voice selector over a host-supplied `catalog`, mirroring `lyra-model-select`'s
11399
+ closed-dropdown/free-text-combobox dual mode, stale-value handling, and form-association verbatim
11400
+ (see that section for the full mode-switching contract this one shares), extended with a
11401
+ TTS-agnostic preview affordance. Preview is event-first: `lyra-preview-request` always fires first
11402
+ and is cancelable — left un-prevented, a `previewUrl` plays through one internal native `<audio>`
11403
+ (validated by `safeMediaSrc()` first); `preventDefault()` or no URL leaves playback to the host's own
11404
+ TTS. Requesting the same voice while it's already playing internally stops it instead of
11405
+ re-requesting; requesting a different voice switches. Does not synthesize speech, fetch catalogs, or
11406
+ persist selection; not a persona picker; `lyra-model-select` stays for LLMs.
11407
+
11408
+ **Exported types:** `LyraVoiceCatalogEntry { id: string; label: string; language?: string;
11409
+ description?: string; previewUrl?: string }` — `language`/`description` render as a quiet
11410
+ `[part="option-meta"]` second line. `LyraVoiceCatalog = string[] | LyraVoiceCatalogEntry[]` —
11411
+ homogeneous, same union contract as `LyraModelCatalog`.
11412
+
11413
+ **Properties:** `provider: string = ''` — informational only (e.g. `'elevenlabs'`); rendered as a
11414
+ small leading badge. `catalog?: LyraVoiceCatalog` (attribute: false) — the full voice list; omit (or
11415
+ leave empty) to fall back to plain free-text entry. `allowCustom: boolean = false` (attribute
11416
+ `allow-custom`, reflected) — let the user type/commit a value that isn't in `catalog`. `preview:
11417
+ boolean = true` (reflected) — whether to render preview affordances at all. `label: string = ''`,
11418
+ `hint: string = ''`, `errorText: string = ''` (attribute `error-text`), `placeholder: string = ''`,
11419
+ `spellcheck: boolean = true` (string-aware converter, same as `lyra-model-select`), `autocapitalize:
11420
+ string = ''`, `autoCorrect: string = ''` (attribute `autocorrect`), `autocomplete: string = 'off'`,
11421
+ `inputMode: string = ''` (attribute `inputmode`), `enterKeyHint: string = ''` (attribute
11422
+ `enterkeyhint`), and `open: boolean = false` (reflected) — all mirror `lyra-model-select`'s
11423
+ identically-named properties.
11424
+
11425
+ **Form association:** hand-rolled via `attachInternals()`, mirroring `lyra-model-select`: `value`
11426
+ getter/setter (the current voice id, `''` when nothing is selected), `name` (reflected), `disabled`
11427
+ (reflected), `required` (reflected — enforced via `internals.setValidity()`).
11428
+
11429
+ **Events:** `lyra-change` — `detail: { value, inCatalog }`. `lyra-preview-request` — `detail: {
11430
+ voiceId, previewUrl? }`, cancelable. `lyra-preview-change` — `detail: { voiceId }`, internal playback
11431
+ started (`voiceId`) or stopped (`null`). Plus mirrored native `input`/`change` and re-dispatched
11432
+ `focus`/`blur` (picker-family contract, same as `lyra-model-select`).
11433
+
11434
+ **Slots:** `hint`, `error`.
11435
+
11436
+ **CSS parts:** `form-control-label`, `trigger` (closed-dropdown mode), `combobox`/`combobox-input`
11437
+ (free-text mode), `provider-badge`, `listbox`, `option`, `option-label`, `option-meta` (the quiet
11438
+ `language · description` second line), `option-badge` (the "not in catalog" badge on a synthetic
11439
+ stale-value row), `option-preview` (a pointer-only per-row preview icon, `tabindex="-1"`,
11440
+ `aria-hidden`), `preview-button` (the standalone, keyboard-reachable preview toggle beside the
11441
+ trigger), `expand-icon`, `empty`, `hint`, `error`.
11442
+
11443
+ ```html
11444
+ <lyra-voice-picker provider="elevenlabs" .catalog=${voices} allow-custom
11445
+ @lyra-change=${(e) => setVoice(e.detail.value)}
11446
+ @lyra-preview-request=${(e) => {
11447
+ if (!e.detail.previewUrl) {
11448
+ e.preventDefault();
11449
+ playSample(e.detail.voiceId);
11450
+ }
11451
+ }}
11452
+ ></lyra-voice-picker>
11453
+ ```
11454
+
11455
+ **Known gotchas:**
11456
+ - Listbox options must not contain tab-focusable controls, so preview is accessible via the
11457
+ standalone `[part="preview-button"]` beside the trigger (previews the active option while open,
11458
+ else the committed value) — the per-row `[part="option-preview"]` icon is a pointer-only
11459
+ duplicate (`tabindex="-1"`, `aria-hidden="true"`).
11460
+ - `catalog` must be homogeneous — the same constraint `lyra-model-select`'s `LyraModelCatalog` union
11461
+ documents.
11462
+
11463
+ ## `lyra-notebook-viewer`
11464
+
11465
+ Read-only Jupyter notebook (nbformat 4.x) renderer, composing existing components per cell.
11466
+ Execution is a hard non-goal. Markdown cells render through `lyra-markdown`, code cells through
11467
+ `lyra-code-block` (using the notebook's kernel language for syntax highlighting), and raw cells as
11468
+ plain preformatted text. A code cell's `execute_result`/`display_data` outputs prefer, in order,
11469
+ `image/png`, `image/jpeg`, `image/svg+xml` (sanitized), `text/html` (sanitized), `application/json`
11470
+ (via `lyra-json-viewer`), then `text/plain`. Stream/error outputs render as plain preformatted text
11471
+ (tinted `danger` for stderr/tracebacks). Sanitizing raw HTML/SVG output markup lazy-loads the
11472
+ optional peer `dompurify`; without it, the output renders a localized notice instead of raw markup.
11473
+ Cells are virtualized through `lyra-virtual-list`. `node-path` anchors resolve `path[0]` as a cell
11474
+ index; `fragment` anchors resolve a cell's own `id`. No execution, no kernels, no editing, no
11475
+ ipywidgets.
11476
+
11477
+ **Properties:** `src: string = ''` — URL to fetch and parse as a notebook; ignored once `notebook` is
11478
+ set. `notebook?: object | string` (property only) — an already-parsed notebook document, or its raw
11479
+ JSON text; wins over `src` and is parsed (and validated) synchronously. `name: string = ''` —
11480
+ accessible label, and matched against a `fragment` anchor's cell id. `outputCollapseLines: number =
11481
+ 40` (attribute `output-collapse-lines`) — a plain-text output longer than this many lines renders
11482
+ collapsed behind a toggle; `0` disables collapsing. `maxHeight: string = ''` (attribute
11483
+ `max-height`) — once set, the notebook scrolls internally past this height. `anchorKinds` is a
11484
+ readonly `['node-path', 'fragment']` (this viewer's supported `LyraAnchor.kind` values for the
11485
+ shared anchor-target contract).
11486
+
11487
+ **Methods:** `search(query)` resolves the match count over cell sources and text outputs — a
11488
+ matching cell counts as one match (empty/whitespace query behaves like `clearSearch()`);
11489
+ `searchNext()`/`searchPrevious()` advance/step back through matches, scrolling to and flashing the
11490
+ target cell; `clearSearch()` clears the query and matches.
11491
+
11492
+ **Events:** `lyra-load` — `detail: { cellCount, language }`, fired once a notebook has been parsed
11493
+ and validated (`language` from `metadata.language_info.name`/`kernelspec.language`, else `''`).
11494
+ `lyra-highlight-activate` — `detail: { id }`. `lyra-search-change` — `detail: { query, matchCount,
11495
+ activeIndex }`. `lyra-render-error` — `detail: { error }`, fetching, parsing, or validating the
11496
+ notebook failed.
11497
+
11498
+ **CSS parts:** `base` (the root scroll container), `cell` (`data-cell-type="code|markdown|raw"`,
11499
+ `data-active`), `cell-gutter` (the `In [n]`/`Out [n]` label column), `cell-source`, `outputs`,
11500
+ `output` (`data-output-type`, `data-stream`), `output-toggle`, `error`, `spinner`.
11501
+
11502
+ **Themeable custom properties:** `--lyra-notebook-viewer-max-height` (default `none`).
11503
+
11504
+ **Optional peer deps:** `marked`+`dompurify` (markdown cells, falls back to plain text per cell),
11505
+ `shiki` (code cells, falls back to unhighlighted), `dompurify` (HTML/SVG outputs, falls back to
11506
+ `text/plain`).
11507
+
11508
+ ```html
11509
+ <lyra-notebook-viewer .notebook=${result} max-height="30rem"
11510
+ @lyra-load=${(e) => console.log(e.detail.cellCount, 'cells')}
11511
+ ></lyra-notebook-viewer>
11512
+ ```
11513
+
11514
+ A notebook major version outside 4.0–4.5, an invalid shape, or more than 2,000 cells renders a
11515
+ localized error and fires `lyra-render-error` instead of the notebook.
11516
+
11517
+ ## `lyra-xml-viewer`
11518
+
11519
+ Collapsible, copyable, `DOMParser`-based tree view for XML documents, mirroring `lyra-json-viewer`'s
11520
+ UX (`collapsed-depth`, `copyable`, structural-path-keyed expand state that survives a same-shape
11521
+ `xml` reassignment) adapted for XML's own node kinds: elements with attributes, text, comments, CDATA
11522
+ sections, and processing instructions. Namespace-literal: qualified names render exactly as authored,
11523
+ with no namespace-URI-aware matching. `DOMParser` never resolves external entities or DTDs, so XXE
11524
+ injection is structurally out of reach. Not `lyra-json-viewer` (JS values); not `lyra-html-viewer`
11525
+ (sanitized *rendered* HTML). No XPath/XSLT evaluation, no editing, no schema validation.
11526
+
11527
+ **Properties:** `src: string = ''` — URL to fetch and parse; ignored once `xml` is set. `xml?:
11528
+ string` (property only) — raw XML text to parse and render; wins over `src`, and setting it parses
11529
+ synchronously. `name: string = ''` — accessible label. `collapsedDepth?: number` (attribute
11530
+ `collapsed-depth`) — elements at or beyond this nesting depth (root = 0) start collapsed. `copyable:
11531
+ boolean = false` (reflected) — shows copy-to-clipboard affordances, one for the whole document plus
11532
+ one per element. `maxHeight: string = ''` (attribute `max-height`). `anchorKinds` is a readonly
11533
+ `['node-path']` (this viewer's supported `LyraAnchor.kind` values for the shared anchor-target
11534
+ contract) — each numeric path segment is the 0-based index within the parent's *element* children,
11535
+ and an optional trailing string segment `'@attrName'` addresses one attribute.
11536
+
11537
+ **Methods:** `search(query)` resolves the match count via a case-insensitive substring search over
11538
+ every element's tag name, attribute names/values, and own text (empty/whitespace query behaves like
11539
+ `clearSearch()`); `searchNext()`/`searchPrevious()` advance/step back through matches (wrapping);
11540
+ `clearSearch()` clears the query and matches.
11541
+
11542
+ **Events:** `lyra-copy` — `detail: { text }`. `lyra-search-change` — `detail: { query, matchCount,
11543
+ activeIndex }`. `lyra-render-error` — `detail: { error }`, fetching or parsing failed, including a
11544
+ parse error or exceeding the node cap.
11545
+
11546
+ **CSS parts:** `base`, `toolbar` (the whole-document copy button row, only when `copyable`),
11547
+ `copy-button` (the whole-document one, or a per-node one), `tree`, `node` (`data-active` while it's
11548
+ the resolved anchor target, `data-match`, `data-active-match`), `tag` (`data-match`), `attribute`,
11549
+ `attribute-name`, `attribute-value` (`data-match`), `text` (`data-match`), `comment`, `cdata`, `pi`,
11550
+ `toggle` (an element's expand/collapse button, hidden but present for row alignment on leaf/empty
11551
+ elements), `error`, `spinner`.
11552
+
11553
+ **Themeable custom properties:** `--lyra-xml-viewer-max-height` (default `none`).
11554
+
11555
+ ```html
11556
+ <lyra-xml-viewer .xml=${payload} collapsed-depth="2" copyable
11557
+ search=${query}
11558
+ ></lyra-xml-viewer>
11559
+ ```
11560
+
11561
+ Node cap: 50,000 — exceeding it renders the localized `xmlViewerTooManyNodes` error instead of the
11562
+ tree.
11563
+
11564
+ ## `lyra-geojson-view`
11565
+
11566
+ Internal document-registry bridge that fetches, validates, and renders a GeoJSON file through
11567
+ `<lyra-map>`'s `dataLayers` — not a documented public tag: excluded from the README/llms family
11568
+ tables, present in the generated manifest since a defined custom element is technically reachable.
11569
+ The document registry matches `application/geo+json` and `.geojson` filenames.
11570
+
11571
+ Validates the parsed JSON is a `Feature`/`FeatureCollection`/bare geometry (one of `Point`,
11572
+ `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon`, `GeometryCollection`) before
11573
+ rendering; anything else renders the localized `geojsonViewInvalid` error. On success, it walks every
11574
+ coordinate to compute a bounding box and fits a `center`/`zoom` to it (a Web-Mercator-fit
11575
+ approximation weighting latitude span ~2x, with 40% padding), then hands the parsed value to
11576
+ `<lyra-map>` as a single `dataLayers` entry (`sourceId: 'lyra-geojson'`). When the optional
11577
+ `maplibre-gl` peer isn't installed, it falls back to a status line plus a `<lyra-json-viewer
11578
+ collapsed-depth="2">` of the raw value instead of the map.
11579
+
11580
+ **Properties:** `src: string = ''` — URL to fetch and parse. `name: string = ''` — accessible label,
11581
+ used as `<lyra-map>`'s `label` and the root's `aria-label` (falling back to the localized
11582
+ `geojsonViewLabel` when unset).
11583
+
11584
+ **Events:** `lyra-render-error` — `detail: { error }` — fetch, parse, or shape-validation failure.
11585
+
11586
+ **CSS parts:** `base` (the root container), `status` (the feature-count status line, `role="status"`,
11587
+ shown only in the `<lyra-map>` path), `missing-library` (the missing-`maplibre-gl` callout shown
11588
+ alongside the `lyra-json-viewer` fallback), `error` (the error region, `role="alert"`), `spinner`
11589
+ (the loading status region).
11590
+
11591
+ Registered by importing `geojson-view/geojson-view.js` directly — not part of the root barrel, the
11592
+ same as `lyra-map`/`lyra-graph`, since it depends on the same optional `maplibre-gl` peer. Remote
11593
+ resources are capped at 25 MB; exceeding it surfaces the localized `documentPreviewResourceTooLarge`
11594
+ message instead of the map.