@aceshooting/lyra-ui 3.6.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 (1324) hide show
  1. package/README.md +109 -3
  2. package/custom-elements.json +91136 -42119
  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 +32 -4
  109. package/dist/components/button/button.class.d.ts.map +1 -1
  110. package/dist/components/button/button.class.js +43 -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 +33 -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 +5 -1
  468. package/dist/components/file-icon/file-icon.class.d.ts.map +1 -1
  469. package/dist/components/file-icon/file-icon.class.js +25 -2
  470. package/dist/components/file-icon/file-icon.class.js.map +1 -1
  471. package/dist/components/file-icon/file-icon.styles.d.ts.map +1 -1
  472. package/dist/components/file-icon/file-icon.styles.js +4 -0
  473. package/dist/components/file-icon/file-icon.styles.js.map +1 -1
  474. package/dist/components/file-input/file-input.class.d.ts +19 -0
  475. package/dist/components/file-input/file-input.class.d.ts.map +1 -1
  476. package/dist/components/file-input/file-input.class.js +27 -1
  477. package/dist/components/file-input/file-input.class.js.map +1 -1
  478. package/dist/components/file-tree/file-tree.class.d.ts +68 -0
  479. package/dist/components/file-tree/file-tree.class.d.ts.map +1 -0
  480. package/dist/components/file-tree/file-tree.class.js +235 -0
  481. package/dist/components/file-tree/file-tree.class.js.map +1 -0
  482. package/dist/components/file-tree/file-tree.d.ts +2 -0
  483. package/dist/components/file-tree/file-tree.d.ts.map +1 -0
  484. package/dist/components/file-tree/file-tree.js +5 -0
  485. package/dist/components/file-tree/file-tree.js.map +1 -0
  486. package/dist/components/file-tree/file-tree.styles.d.ts +2 -0
  487. package/dist/components/file-tree/file-tree.styles.d.ts.map +1 -0
  488. package/dist/components/file-tree/file-tree.styles.js +10 -0
  489. package/dist/components/file-tree/file-tree.styles.js.map +1 -0
  490. package/dist/components/flag/flag.class.d.ts.map +1 -1
  491. package/dist/components/flag/flag.class.js +7 -15
  492. package/dist/components/flag/flag.class.js.map +1 -1
  493. package/dist/components/flow-canvas/flow-canvas.class.d.ts +411 -0
  494. package/dist/components/flow-canvas/flow-canvas.class.d.ts.map +1 -0
  495. package/dist/components/flow-canvas/flow-canvas.class.js +1570 -0
  496. package/dist/components/flow-canvas/flow-canvas.class.js.map +1 -0
  497. package/dist/components/flow-canvas/flow-canvas.d.ts +4 -0
  498. package/dist/components/flow-canvas/flow-canvas.d.ts.map +1 -0
  499. package/dist/components/flow-canvas/flow-canvas.js +7 -0
  500. package/dist/components/flow-canvas/flow-canvas.js.map +1 -0
  501. package/dist/components/flow-canvas/flow-canvas.styles.d.ts +2 -0
  502. package/dist/components/flow-canvas/flow-canvas.styles.d.ts.map +1 -0
  503. package/dist/components/flow-canvas/flow-canvas.styles.js +186 -0
  504. package/dist/components/flow-canvas/flow-canvas.styles.js.map +1 -0
  505. package/dist/components/flow-controls/flow-controls.class.d.ts +44 -0
  506. package/dist/components/flow-controls/flow-controls.class.d.ts.map +1 -0
  507. package/dist/components/flow-controls/flow-controls.class.js +203 -0
  508. package/dist/components/flow-controls/flow-controls.class.js.map +1 -0
  509. package/dist/components/flow-controls/flow-controls.d.ts +2 -0
  510. package/dist/components/flow-controls/flow-controls.d.ts.map +1 -0
  511. package/dist/components/flow-controls/flow-controls.js +5 -0
  512. package/dist/components/flow-controls/flow-controls.js.map +1 -0
  513. package/dist/components/flow-controls/flow-controls.styles.d.ts +2 -0
  514. package/dist/components/flow-controls/flow-controls.styles.d.ts.map +1 -0
  515. package/dist/components/flow-controls/flow-controls.styles.js +55 -0
  516. package/dist/components/flow-controls/flow-controls.styles.js.map +1 -0
  517. package/dist/components/flow-minimap/flow-minimap.class.d.ts +62 -0
  518. package/dist/components/flow-minimap/flow-minimap.class.d.ts.map +1 -0
  519. package/dist/components/flow-minimap/flow-minimap.class.js +291 -0
  520. package/dist/components/flow-minimap/flow-minimap.class.js.map +1 -0
  521. package/dist/components/flow-minimap/flow-minimap.d.ts +2 -0
  522. package/dist/components/flow-minimap/flow-minimap.d.ts.map +1 -0
  523. package/dist/components/flow-minimap/flow-minimap.js +5 -0
  524. package/dist/components/flow-minimap/flow-minimap.js.map +1 -0
  525. package/dist/components/flow-minimap/flow-minimap.styles.d.ts +2 -0
  526. package/dist/components/flow-minimap/flow-minimap.styles.d.ts.map +1 -0
  527. package/dist/components/flow-minimap/flow-minimap.styles.js +48 -0
  528. package/dist/components/flow-minimap/flow-minimap.styles.js.map +1 -0
  529. package/dist/components/flow-node/flow-node.class.d.ts +70 -0
  530. package/dist/components/flow-node/flow-node.class.d.ts.map +1 -0
  531. package/dist/components/flow-node/flow-node.class.js +187 -0
  532. package/dist/components/flow-node/flow-node.class.js.map +1 -0
  533. package/dist/components/flow-node/flow-node.d.ts +2 -0
  534. package/dist/components/flow-node/flow-node.d.ts.map +1 -0
  535. package/dist/components/flow-node/flow-node.js +5 -0
  536. package/dist/components/flow-node/flow-node.js.map +1 -0
  537. package/dist/components/flow-node/flow-node.styles.d.ts +2 -0
  538. package/dist/components/flow-node/flow-node.styles.d.ts.map +1 -0
  539. package/dist/components/flow-node/flow-node.styles.js +127 -0
  540. package/dist/components/flow-node/flow-node.styles.js.map +1 -0
  541. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts +46 -0
  542. package/dist/components/flow-run-overlay/flow-run-overlay.class.d.ts.map +1 -0
  543. package/dist/components/flow-run-overlay/flow-run-overlay.class.js +182 -0
  544. package/dist/components/flow-run-overlay/flow-run-overlay.class.js.map +1 -0
  545. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts +2 -0
  546. package/dist/components/flow-run-overlay/flow-run-overlay.d.ts.map +1 -0
  547. package/dist/components/flow-run-overlay/flow-run-overlay.js +5 -0
  548. package/dist/components/flow-run-overlay/flow-run-overlay.js.map +1 -0
  549. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts +2 -0
  550. package/dist/components/flow-run-overlay/flow-run-overlay.styles.d.ts.map +1 -0
  551. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js +38 -0
  552. package/dist/components/flow-run-overlay/flow-run-overlay.styles.js.map +1 -0
  553. package/dist/components/format/format-bytes.class.d.ts +8 -0
  554. package/dist/components/format/format-bytes.class.d.ts.map +1 -1
  555. package/dist/components/format/format-bytes.class.js +36 -7
  556. package/dist/components/format/format-bytes.class.js.map +1 -1
  557. package/dist/components/format/format-date.class.d.ts.map +1 -1
  558. package/dist/components/format/format-date.class.js +2 -1
  559. package/dist/components/format/format-date.class.js.map +1 -1
  560. package/dist/components/format/format-number.class.d.ts +6 -0
  561. package/dist/components/format/format-number.class.d.ts.map +1 -1
  562. package/dist/components/format/format-number.class.js +34 -5
  563. package/dist/components/format/format-number.class.js.map +1 -1
  564. package/dist/components/format/relative-time.class.d.ts.map +1 -1
  565. package/dist/components/format/relative-time.class.js +2 -1
  566. package/dist/components/format/relative-time.class.js.map +1 -1
  567. package/dist/components/generation-status/generation-status.class.d.ts +3 -0
  568. package/dist/components/generation-status/generation-status.class.d.ts.map +1 -1
  569. package/dist/components/generation-status/generation-status.class.js +28 -11
  570. package/dist/components/generation-status/generation-status.class.js.map +1 -1
  571. package/dist/components/generation-status/generation-status.styles.d.ts.map +1 -1
  572. package/dist/components/generation-status/generation-status.styles.js +7 -4
  573. package/dist/components/generation-status/generation-status.styles.js.map +1 -1
  574. package/dist/components/geojson-view/geojson-view.class.d.ts +40 -0
  575. package/dist/components/geojson-view/geojson-view.class.d.ts.map +1 -0
  576. package/dist/components/geojson-view/geojson-view.class.js +185 -0
  577. package/dist/components/geojson-view/geojson-view.class.js.map +1 -0
  578. package/dist/components/geojson-view/geojson-view.d.ts +5 -0
  579. package/dist/components/geojson-view/geojson-view.d.ts.map +1 -0
  580. package/dist/components/geojson-view/geojson-view.js +18 -0
  581. package/dist/components/geojson-view/geojson-view.js.map +1 -0
  582. package/dist/components/graph/graph-canvas.d.ts +110 -0
  583. package/dist/components/graph/graph-canvas.d.ts.map +1 -0
  584. package/dist/components/graph/graph-canvas.js +175 -0
  585. package/dist/components/graph/graph-canvas.js.map +1 -0
  586. package/dist/components/graph/graph-hull.d.ts +28 -0
  587. package/dist/components/graph/graph-hull.d.ts.map +1 -0
  588. package/dist/components/graph/graph-hull.js +70 -0
  589. package/dist/components/graph/graph-hull.js.map +1 -0
  590. package/dist/components/graph/graph-loader.d.ts +6 -0
  591. package/dist/components/graph/graph-loader.d.ts.map +1 -1
  592. package/dist/components/graph/graph-loader.js +2 -0
  593. package/dist/components/graph/graph-loader.js.map +1 -1
  594. package/dist/components/graph/graph.class.d.ts +447 -2
  595. package/dist/components/graph/graph.class.d.ts.map +1 -1
  596. package/dist/components/graph/graph.class.js +1700 -121
  597. package/dist/components/graph/graph.class.js.map +1 -1
  598. package/dist/components/graph/graph.styles.d.ts.map +1 -1
  599. package/dist/components/graph/graph.styles.js +100 -0
  600. package/dist/components/graph/graph.styles.js.map +1 -1
  601. package/dist/components/graph-legend/graph-legend.class.d.ts +62 -0
  602. package/dist/components/graph-legend/graph-legend.class.d.ts.map +1 -0
  603. package/dist/components/graph-legend/graph-legend.class.js +132 -0
  604. package/dist/components/graph-legend/graph-legend.class.js.map +1 -0
  605. package/dist/components/graph-legend/graph-legend.d.ts +2 -0
  606. package/dist/components/graph-legend/graph-legend.d.ts.map +1 -0
  607. package/dist/components/graph-legend/graph-legend.js +5 -0
  608. package/dist/components/graph-legend/graph-legend.js.map +1 -0
  609. package/dist/components/graph-legend/graph-legend.styles.d.ts +2 -0
  610. package/dist/components/graph-legend/graph-legend.styles.d.ts.map +1 -0
  611. package/dist/components/graph-legend/graph-legend.styles.js +59 -0
  612. package/dist/components/graph-legend/graph-legend.styles.js.map +1 -0
  613. package/dist/components/handoff-divider/handoff-divider.class.d.ts +46 -0
  614. package/dist/components/handoff-divider/handoff-divider.class.d.ts.map +1 -0
  615. package/dist/components/handoff-divider/handoff-divider.class.js +99 -0
  616. package/dist/components/handoff-divider/handoff-divider.class.js.map +1 -0
  617. package/dist/components/handoff-divider/handoff-divider.d.ts +2 -0
  618. package/dist/components/handoff-divider/handoff-divider.d.ts.map +1 -0
  619. package/dist/components/handoff-divider/handoff-divider.js +5 -0
  620. package/dist/components/handoff-divider/handoff-divider.js.map +1 -0
  621. package/dist/components/handoff-divider/handoff-divider.styles.d.ts +2 -0
  622. package/dist/components/handoff-divider/handoff-divider.styles.d.ts.map +1 -0
  623. package/dist/components/handoff-divider/handoff-divider.styles.js +48 -0
  624. package/dist/components/handoff-divider/handoff-divider.styles.js.map +1 -0
  625. package/dist/components/heatmap/heatmap.class.d.ts +12 -3
  626. package/dist/components/heatmap/heatmap.class.d.ts.map +1 -1
  627. package/dist/components/heatmap/heatmap.class.js +88 -50
  628. package/dist/components/heatmap/heatmap.class.js.map +1 -1
  629. package/dist/components/highlight-layer/highlight-layer.class.d.ts +60 -0
  630. package/dist/components/highlight-layer/highlight-layer.class.d.ts.map +1 -0
  631. package/dist/components/highlight-layer/highlight-layer.class.js +151 -0
  632. package/dist/components/highlight-layer/highlight-layer.class.js.map +1 -0
  633. package/dist/components/highlight-layer/highlight-layer.d.ts +2 -0
  634. package/dist/components/highlight-layer/highlight-layer.d.ts.map +1 -0
  635. package/dist/components/highlight-layer/highlight-layer.js +5 -0
  636. package/dist/components/highlight-layer/highlight-layer.js.map +1 -0
  637. package/dist/components/highlight-layer/highlight-layer.styles.d.ts +2 -0
  638. package/dist/components/highlight-layer/highlight-layer.styles.d.ts.map +1 -0
  639. package/dist/components/highlight-layer/highlight-layer.styles.js +68 -0
  640. package/dist/components/highlight-layer/highlight-layer.styles.js.map +1 -0
  641. package/dist/components/image-comparer/image-comparer.class.d.ts.map +1 -1
  642. package/dist/components/image-comparer/image-comparer.class.js +2 -1
  643. package/dist/components/image-comparer/image-comparer.class.js.map +1 -1
  644. package/dist/components/image-viewer/image-viewer.class.d.ts +143 -0
  645. package/dist/components/image-viewer/image-viewer.class.d.ts.map +1 -0
  646. package/dist/components/image-viewer/image-viewer.class.js +389 -0
  647. package/dist/components/image-viewer/image-viewer.class.js.map +1 -0
  648. package/dist/components/image-viewer/image-viewer.d.ts +4 -0
  649. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  650. package/dist/components/image-viewer/image-viewer.js +25 -0
  651. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  652. package/dist/components/image-viewer/image-viewer.styles.d.ts +2 -0
  653. package/dist/components/image-viewer/image-viewer.styles.d.ts.map +1 -0
  654. package/dist/components/image-viewer/image-viewer.styles.js +126 -0
  655. package/dist/components/image-viewer/image-viewer.styles.js.map +1 -0
  656. package/dist/components/input/input.class.d.ts +3 -2
  657. package/dist/components/input/input.class.d.ts.map +1 -1
  658. package/dist/components/input/input.class.js +2 -1
  659. package/dist/components/input/input.class.js.map +1 -1
  660. package/dist/components/input/input.styles.d.ts.map +1 -1
  661. package/dist/components/input/input.styles.js +5 -0
  662. package/dist/components/input/input.styles.js.map +1 -1
  663. package/dist/components/intersection-observer/intersection-observer.class.d.ts +1 -0
  664. package/dist/components/intersection-observer/intersection-observer.class.d.ts.map +1 -1
  665. package/dist/components/intersection-observer/intersection-observer.class.js +15 -0
  666. package/dist/components/intersection-observer/intersection-observer.class.js.map +1 -1
  667. package/dist/components/json-viewer/json-viewer.class.d.ts +39 -2
  668. package/dist/components/json-viewer/json-viewer.class.d.ts.map +1 -1
  669. package/dist/components/json-viewer/json-viewer.class.js +95 -6
  670. package/dist/components/json-viewer/json-viewer.class.js.map +1 -1
  671. package/dist/components/known-date/known-date.class.d.ts.map +1 -1
  672. package/dist/components/known-date/known-date.class.js +2 -1
  673. package/dist/components/known-date/known-date.class.js.map +1 -1
  674. package/dist/components/lightbox/lightbox.class.d.ts +2 -2
  675. package/dist/components/lightbox/lightbox.class.d.ts.map +1 -1
  676. package/dist/components/lightbox/lightbox.class.js +16 -7
  677. package/dist/components/lightbox/lightbox.class.js.map +1 -1
  678. package/dist/components/live-region/live-region.class.d.ts +5 -0
  679. package/dist/components/live-region/live-region.class.d.ts.map +1 -1
  680. package/dist/components/live-region/live-region.class.js +10 -2
  681. package/dist/components/live-region/live-region.class.js.map +1 -1
  682. package/dist/components/map/map.class.d.ts +33 -3
  683. package/dist/components/map/map.class.d.ts.map +1 -1
  684. package/dist/components/map/map.class.js +140 -5
  685. package/dist/components/map/map.class.js.map +1 -1
  686. package/dist/components/markdown/katex-loader.d.ts +23 -0
  687. package/dist/components/markdown/katex-loader.d.ts.map +1 -0
  688. package/dist/components/markdown/katex-loader.js +33 -0
  689. package/dist/components/markdown/katex-loader.js.map +1 -0
  690. package/dist/components/markdown/markdown.class.d.ts +191 -4
  691. package/dist/components/markdown/markdown.class.d.ts.map +1 -1
  692. package/dist/components/markdown/markdown.class.js +584 -11
  693. package/dist/components/markdown/markdown.class.js.map +1 -1
  694. package/dist/components/markdown/markdown.styles.d.ts.map +1 -1
  695. package/dist/components/markdown/markdown.styles.js +53 -0
  696. package/dist/components/markdown/markdown.styles.js.map +1 -1
  697. package/dist/components/media-card/media-card.styles.d.ts.map +1 -1
  698. package/dist/components/media-card/media-card.styles.js +6 -2
  699. package/dist/components/media-card/media-card.styles.js.map +1 -1
  700. package/dist/components/mention-popover/mention-popover.styles.d.ts.map +1 -1
  701. package/dist/components/mention-popover/mention-popover.styles.js +6 -3
  702. package/dist/components/mention-popover/mention-popover.styles.js.map +1 -1
  703. package/dist/components/message-actions/message-actions.class.d.ts +112 -0
  704. package/dist/components/message-actions/message-actions.class.d.ts.map +1 -0
  705. package/dist/components/message-actions/message-actions.class.js +277 -0
  706. package/dist/components/message-actions/message-actions.class.js.map +1 -0
  707. package/dist/components/message-actions/message-actions.d.ts +4 -0
  708. package/dist/components/message-actions/message-actions.d.ts.map +1 -0
  709. package/dist/components/message-actions/message-actions.js +7 -0
  710. package/dist/components/message-actions/message-actions.js.map +1 -0
  711. package/dist/components/message-actions/message-actions.styles.d.ts +2 -0
  712. package/dist/components/message-actions/message-actions.styles.d.ts.map +1 -0
  713. package/dist/components/message-actions/message-actions.styles.js +66 -0
  714. package/dist/components/message-actions/message-actions.styles.js.map +1 -0
  715. package/dist/components/message-feedback/message-feedback.class.d.ts +91 -0
  716. package/dist/components/message-feedback/message-feedback.class.d.ts.map +1 -0
  717. package/dist/components/message-feedback/message-feedback.class.js +266 -0
  718. package/dist/components/message-feedback/message-feedback.class.js.map +1 -0
  719. package/dist/components/message-feedback/message-feedback.d.ts +2 -0
  720. package/dist/components/message-feedback/message-feedback.d.ts.map +1 -0
  721. package/dist/components/message-feedback/message-feedback.js +5 -0
  722. package/dist/components/message-feedback/message-feedback.js.map +1 -0
  723. package/dist/components/message-feedback/message-feedback.styles.d.ts +2 -0
  724. package/dist/components/message-feedback/message-feedback.styles.d.ts.map +1 -0
  725. package/dist/components/message-feedback/message-feedback.styles.js +133 -0
  726. package/dist/components/message-feedback/message-feedback.styles.js.map +1 -0
  727. package/dist/components/mind-map/mind-map-layout.d.ts +52 -0
  728. package/dist/components/mind-map/mind-map-layout.d.ts.map +1 -0
  729. package/dist/components/mind-map/mind-map-layout.js +69 -0
  730. package/dist/components/mind-map/mind-map-layout.js.map +1 -0
  731. package/dist/components/mind-map/mind-map.class.d.ts +83 -0
  732. package/dist/components/mind-map/mind-map.class.d.ts.map +1 -0
  733. package/dist/components/mind-map/mind-map.class.js +252 -0
  734. package/dist/components/mind-map/mind-map.class.js.map +1 -0
  735. package/dist/components/mind-map/mind-map.d.ts +2 -0
  736. package/dist/components/mind-map/mind-map.d.ts.map +1 -0
  737. package/dist/components/mind-map/mind-map.js +5 -0
  738. package/dist/components/mind-map/mind-map.js.map +1 -0
  739. package/dist/components/mind-map/mind-map.styles.d.ts +2 -0
  740. package/dist/components/mind-map/mind-map.styles.d.ts.map +1 -0
  741. package/dist/components/mind-map/mind-map.styles.js +43 -0
  742. package/dist/components/mind-map/mind-map.styles.js.map +1 -0
  743. package/dist/components/model-select/model-select.class.d.ts +1 -0
  744. package/dist/components/model-select/model-select.class.d.ts.map +1 -1
  745. package/dist/components/model-select/model-select.class.js +13 -0
  746. package/dist/components/model-select/model-select.class.js.map +1 -1
  747. package/dist/components/mutation-observer/mutation-observer.class.d.ts +1 -0
  748. package/dist/components/mutation-observer/mutation-observer.class.d.ts.map +1 -1
  749. package/dist/components/mutation-observer/mutation-observer.class.js +15 -0
  750. package/dist/components/mutation-observer/mutation-observer.class.js.map +1 -1
  751. package/dist/components/neighbor-list/neighbor-list.class.d.ts +70 -0
  752. package/dist/components/neighbor-list/neighbor-list.class.d.ts.map +1 -0
  753. package/dist/components/neighbor-list/neighbor-list.class.js +177 -0
  754. package/dist/components/neighbor-list/neighbor-list.class.js.map +1 -0
  755. package/dist/components/neighbor-list/neighbor-list.d.ts +4 -0
  756. package/dist/components/neighbor-list/neighbor-list.d.ts.map +1 -0
  757. package/dist/components/neighbor-list/neighbor-list.js +7 -0
  758. package/dist/components/neighbor-list/neighbor-list.js.map +1 -0
  759. package/dist/components/neighbor-list/neighbor-list.styles.d.ts +2 -0
  760. package/dist/components/neighbor-list/neighbor-list.styles.d.ts.map +1 -0
  761. package/dist/components/neighbor-list/neighbor-list.styles.js +79 -0
  762. package/dist/components/neighbor-list/neighbor-list.styles.js.map +1 -0
  763. package/dist/components/node-palette/node-palette.class.d.ts +82 -0
  764. package/dist/components/node-palette/node-palette.class.d.ts.map +1 -0
  765. package/dist/components/node-palette/node-palette.class.js +213 -0
  766. package/dist/components/node-palette/node-palette.class.js.map +1 -0
  767. package/dist/components/node-palette/node-palette.d.ts +2 -0
  768. package/dist/components/node-palette/node-palette.d.ts.map +1 -0
  769. package/dist/components/node-palette/node-palette.js +5 -0
  770. package/dist/components/node-palette/node-palette.js.map +1 -0
  771. package/dist/components/node-palette/node-palette.styles.d.ts +2 -0
  772. package/dist/components/node-palette/node-palette.styles.d.ts.map +1 -0
  773. package/dist/components/node-palette/node-palette.styles.js +74 -0
  774. package/dist/components/node-palette/node-palette.styles.js.map +1 -0
  775. package/dist/components/notebook-viewer/dompurify-loader.d.ts +7 -0
  776. package/dist/components/notebook-viewer/dompurify-loader.d.ts.map +1 -0
  777. package/dist/components/notebook-viewer/dompurify-loader.js +23 -0
  778. package/dist/components/notebook-viewer/dompurify-loader.js.map +1 -0
  779. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts +164 -0
  780. package/dist/components/notebook-viewer/notebook-viewer.class.d.ts.map +1 -0
  781. package/dist/components/notebook-viewer/notebook-viewer.class.js +442 -0
  782. package/dist/components/notebook-viewer/notebook-viewer.class.js.map +1 -0
  783. package/dist/components/notebook-viewer/notebook-viewer.d.ts +6 -0
  784. package/dist/components/notebook-viewer/notebook-viewer.d.ts.map +1 -0
  785. package/dist/components/notebook-viewer/notebook-viewer.js +21 -0
  786. package/dist/components/notebook-viewer/notebook-viewer.js.map +1 -0
  787. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts +2 -0
  788. package/dist/components/notebook-viewer/notebook-viewer.styles.d.ts.map +1 -0
  789. package/dist/components/notebook-viewer/notebook-viewer.styles.js +79 -0
  790. package/dist/components/notebook-viewer/notebook-viewer.styles.js.map +1 -0
  791. package/dist/components/overlay/overlay.styles.d.ts.map +1 -1
  792. package/dist/components/overlay/overlay.styles.js +17 -5
  793. package/dist/components/overlay/overlay.styles.js.map +1 -1
  794. package/dist/components/overlay/popover.class.d.ts +2 -0
  795. package/dist/components/overlay/popover.class.d.ts.map +1 -1
  796. package/dist/components/overlay/popover.class.js +10 -2
  797. package/dist/components/overlay/popover.class.js.map +1 -1
  798. package/dist/components/overlay/tooltip.class.d.ts +4 -0
  799. package/dist/components/overlay/tooltip.class.d.ts.map +1 -1
  800. package/dist/components/overlay/tooltip.class.js +21 -6
  801. package/dist/components/overlay/tooltip.class.js.map +1 -1
  802. package/dist/components/page-rail/page-rail.class.d.ts +99 -0
  803. package/dist/components/page-rail/page-rail.class.d.ts.map +1 -0
  804. package/dist/components/page-rail/page-rail.class.js +279 -0
  805. package/dist/components/page-rail/page-rail.class.js.map +1 -0
  806. package/dist/components/page-rail/page-rail.d.ts +2 -0
  807. package/dist/components/page-rail/page-rail.d.ts.map +1 -0
  808. package/dist/components/page-rail/page-rail.js +5 -0
  809. package/dist/components/page-rail/page-rail.js.map +1 -0
  810. package/dist/components/page-rail/page-rail.styles.d.ts +2 -0
  811. package/dist/components/page-rail/page-rail.styles.d.ts.map +1 -0
  812. package/dist/components/page-rail/page-rail.styles.js +85 -0
  813. package/dist/components/page-rail/page-rail.styles.js.map +1 -0
  814. package/dist/components/pagination/pagination.class.d.ts +5 -0
  815. package/dist/components/pagination/pagination.class.d.ts.map +1 -1
  816. package/dist/components/pagination/pagination.class.js +11 -9
  817. package/dist/components/pagination/pagination.class.js.map +1 -1
  818. package/dist/components/path-strip/path-strip.class.d.ts +61 -0
  819. package/dist/components/path-strip/path-strip.class.d.ts.map +1 -0
  820. package/dist/components/path-strip/path-strip.class.js +164 -0
  821. package/dist/components/path-strip/path-strip.class.js.map +1 -0
  822. package/dist/components/path-strip/path-strip.d.ts +3 -0
  823. package/dist/components/path-strip/path-strip.d.ts.map +1 -0
  824. package/dist/components/path-strip/path-strip.js +6 -0
  825. package/dist/components/path-strip/path-strip.js.map +1 -0
  826. package/dist/components/path-strip/path-strip.styles.d.ts +2 -0
  827. package/dist/components/path-strip/path-strip.styles.d.ts.map +1 -0
  828. package/dist/components/path-strip/path-strip.styles.js +62 -0
  829. package/dist/components/path-strip/path-strip.styles.js.map +1 -0
  830. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts +145 -6
  831. package/dist/components/pdf-viewer/pdf-viewer.class.d.ts.map +1 -1
  832. package/dist/components/pdf-viewer/pdf-viewer.class.js +785 -21
  833. package/dist/components/pdf-viewer/pdf-viewer.class.js.map +1 -1
  834. package/dist/components/pdf-viewer/pdf-viewer.js +7 -1
  835. package/dist/components/pdf-viewer/pdf-viewer.js.map +1 -1
  836. package/dist/components/pdf-viewer/pdf-viewer.styles.d.ts.map +1 -1
  837. package/dist/components/pdf-viewer/pdf-viewer.styles.js +4 -0
  838. package/dist/components/pdf-viewer/pdf-viewer.styles.js.map +1 -1
  839. package/dist/components/phone-input/phone-input.class.d.ts.map +1 -1
  840. package/dist/components/phone-input/phone-input.class.js +5 -1
  841. package/dist/components/phone-input/phone-input.class.js.map +1 -1
  842. package/dist/components/playback/playback.styles.d.ts.map +1 -1
  843. package/dist/components/playback/playback.styles.js +7 -0
  844. package/dist/components/playback/playback.styles.js.map +1 -1
  845. package/dist/components/poll-status/poll-status.class.d.ts +1 -0
  846. package/dist/components/poll-status/poll-status.class.d.ts.map +1 -1
  847. package/dist/components/poll-status/poll-status.class.js +25 -7
  848. package/dist/components/poll-status/poll-status.class.js.map +1 -1
  849. package/dist/components/pptx-viewer/pptx-viewer.styles.d.ts.map +1 -1
  850. package/dist/components/pptx-viewer/pptx-viewer.styles.js +5 -0
  851. package/dist/components/pptx-viewer/pptx-viewer.styles.js.map +1 -1
  852. package/dist/components/progress/progress-bar.class.d.ts +5 -0
  853. package/dist/components/progress/progress-bar.class.d.ts.map +1 -1
  854. package/dist/components/progress/progress-bar.class.js +16 -2
  855. package/dist/components/progress/progress-bar.class.js.map +1 -1
  856. package/dist/components/progress/progress-ring.class.d.ts +5 -0
  857. package/dist/components/progress/progress-ring.class.d.ts.map +1 -1
  858. package/dist/components/progress/progress-ring.class.js +16 -2
  859. package/dist/components/progress/progress-ring.class.js.map +1 -1
  860. package/dist/components/progress/progress.styles.d.ts.map +1 -1
  861. package/dist/components/progress/progress.styles.js +6 -0
  862. package/dist/components/progress/progress.styles.js.map +1 -1
  863. package/dist/components/provenance-panel/provenance-panel.class.d.ts +71 -0
  864. package/dist/components/provenance-panel/provenance-panel.class.d.ts.map +1 -0
  865. package/dist/components/provenance-panel/provenance-panel.class.js +110 -0
  866. package/dist/components/provenance-panel/provenance-panel.class.js.map +1 -0
  867. package/dist/components/provenance-panel/provenance-panel.d.ts +7 -0
  868. package/dist/components/provenance-panel/provenance-panel.d.ts.map +1 -0
  869. package/dist/components/provenance-panel/provenance-panel.js +10 -0
  870. package/dist/components/provenance-panel/provenance-panel.js.map +1 -0
  871. package/dist/components/provenance-panel/provenance-panel.styles.d.ts +2 -0
  872. package/dist/components/provenance-panel/provenance-panel.styles.d.ts.map +1 -0
  873. package/dist/components/provenance-panel/provenance-panel.styles.js +45 -0
  874. package/dist/components/provenance-panel/provenance-panel.styles.js.map +1 -0
  875. package/dist/components/push-to-talk/push-to-talk.class.d.ts +145 -0
  876. package/dist/components/push-to-talk/push-to-talk.class.d.ts.map +1 -0
  877. package/dist/components/push-to-talk/push-to-talk.class.js +478 -0
  878. package/dist/components/push-to-talk/push-to-talk.class.js.map +1 -0
  879. package/dist/components/push-to-talk/push-to-talk.d.ts +3 -0
  880. package/dist/components/push-to-talk/push-to-talk.d.ts.map +1 -0
  881. package/dist/components/push-to-talk/push-to-talk.js +6 -0
  882. package/dist/components/push-to-talk/push-to-talk.js.map +1 -0
  883. package/dist/components/push-to-talk/push-to-talk.styles.d.ts +2 -0
  884. package/dist/components/push-to-talk/push-to-talk.styles.d.ts.map +1 -0
  885. package/dist/components/push-to-talk/push-to-talk.styles.js +79 -0
  886. package/dist/components/push-to-talk/push-to-talk.styles.js.map +1 -0
  887. package/dist/components/radio/radio.class.d.ts +1 -0
  888. package/dist/components/radio/radio.class.d.ts.map +1 -1
  889. package/dist/components/radio/radio.class.js +4 -0
  890. package/dist/components/radio/radio.class.js.map +1 -1
  891. package/dist/components/random-content/random-content.class.d.ts +3 -1
  892. package/dist/components/random-content/random-content.class.d.ts.map +1 -1
  893. package/dist/components/random-content/random-content.class.js +7 -4
  894. package/dist/components/random-content/random-content.class.js.map +1 -1
  895. package/dist/components/rating/rating.class.d.ts +8 -0
  896. package/dist/components/rating/rating.class.d.ts.map +1 -1
  897. package/dist/components/rating/rating.class.js +34 -8
  898. package/dist/components/rating/rating.class.js.map +1 -1
  899. package/dist/components/rubric-form/rubric-form.class.d.ts +195 -0
  900. package/dist/components/rubric-form/rubric-form.class.d.ts.map +1 -0
  901. package/dist/components/rubric-form/rubric-form.class.js +495 -0
  902. package/dist/components/rubric-form/rubric-form.class.js.map +1 -0
  903. package/dist/components/rubric-form/rubric-form.d.ts +9 -0
  904. package/dist/components/rubric-form/rubric-form.d.ts.map +1 -0
  905. package/dist/components/rubric-form/rubric-form.js +12 -0
  906. package/dist/components/rubric-form/rubric-form.js.map +1 -0
  907. package/dist/components/rubric-form/rubric-form.styles.d.ts +2 -0
  908. package/dist/components/rubric-form/rubric-form.styles.d.ts.map +1 -0
  909. package/dist/components/rubric-form/rubric-form.styles.js +90 -0
  910. package/dist/components/rubric-form/rubric-form.styles.js.map +1 -0
  911. package/dist/components/scroller/scroller.class.d.ts +6 -0
  912. package/dist/components/scroller/scroller.class.d.ts.map +1 -1
  913. package/dist/components/scroller/scroller.class.js +14 -4
  914. package/dist/components/scroller/scroller.class.js.map +1 -1
  915. package/dist/components/scroller/scroller.styles.d.ts.map +1 -1
  916. package/dist/components/scroller/scroller.styles.js +18 -0
  917. package/dist/components/scroller/scroller.styles.js.map +1 -1
  918. package/dist/components/segmented/segmented.class.d.ts +1 -0
  919. package/dist/components/segmented/segmented.class.d.ts.map +1 -1
  920. package/dist/components/segmented/segmented.class.js +1 -0
  921. package/dist/components/segmented/segmented.class.js.map +1 -1
  922. package/dist/components/segmented/segmented.styles.d.ts.map +1 -1
  923. package/dist/components/segmented/segmented.styles.js +21 -3
  924. package/dist/components/segmented/segmented.styles.js.map +1 -1
  925. package/dist/components/sequence-strip/sequence-strip.class.d.ts +62 -0
  926. package/dist/components/sequence-strip/sequence-strip.class.d.ts.map +1 -0
  927. package/dist/components/sequence-strip/sequence-strip.class.js +102 -0
  928. package/dist/components/sequence-strip/sequence-strip.class.js.map +1 -0
  929. package/dist/components/sequence-strip/sequence-strip.d.ts +2 -0
  930. package/dist/components/sequence-strip/sequence-strip.d.ts.map +1 -0
  931. package/dist/components/sequence-strip/sequence-strip.js +5 -0
  932. package/dist/components/sequence-strip/sequence-strip.js.map +1 -0
  933. package/dist/components/sequence-strip/sequence-strip.styles.d.ts +2 -0
  934. package/dist/components/sequence-strip/sequence-strip.styles.d.ts.map +1 -0
  935. package/dist/components/sequence-strip/sequence-strip.styles.js +62 -0
  936. package/dist/components/sequence-strip/sequence-strip.styles.js.map +1 -0
  937. package/dist/components/skeleton/skeleton.styles.d.ts.map +1 -1
  938. package/dist/components/skeleton/skeleton.styles.js +7 -0
  939. package/dist/components/skeleton/skeleton.styles.js.map +1 -1
  940. package/dist/components/slider/slider.class.d.ts +6 -1
  941. package/dist/components/slider/slider.class.d.ts.map +1 -1
  942. package/dist/components/slider/slider.class.js +23 -6
  943. package/dist/components/slider/slider.class.js.map +1 -1
  944. package/dist/components/slider/slider.styles.d.ts.map +1 -1
  945. package/dist/components/slider/slider.styles.js +15 -0
  946. package/dist/components/slider/slider.styles.js.map +1 -1
  947. package/dist/components/source-picker/source-picker.class.d.ts +78 -0
  948. package/dist/components/source-picker/source-picker.class.d.ts.map +1 -0
  949. package/dist/components/source-picker/source-picker.class.js +305 -0
  950. package/dist/components/source-picker/source-picker.class.js.map +1 -0
  951. package/dist/components/source-picker/source-picker.d.ts +5 -0
  952. package/dist/components/source-picker/source-picker.d.ts.map +1 -0
  953. package/dist/components/source-picker/source-picker.js +8 -0
  954. package/dist/components/source-picker/source-picker.js.map +1 -0
  955. package/dist/components/source-picker/source-picker.styles.d.ts +2 -0
  956. package/dist/components/source-picker/source-picker.styles.d.ts.map +1 -0
  957. package/dist/components/source-picker/source-picker.styles.js +80 -0
  958. package/dist/components/source-picker/source-picker.styles.js.map +1 -0
  959. package/dist/components/span-waterfall/span-waterfall.class.d.ts +70 -0
  960. package/dist/components/span-waterfall/span-waterfall.class.d.ts.map +1 -0
  961. package/dist/components/span-waterfall/span-waterfall.class.js +307 -0
  962. package/dist/components/span-waterfall/span-waterfall.class.js.map +1 -0
  963. package/dist/components/span-waterfall/span-waterfall.d.ts +4 -0
  964. package/dist/components/span-waterfall/span-waterfall.d.ts.map +1 -0
  965. package/dist/components/span-waterfall/span-waterfall.js +7 -0
  966. package/dist/components/span-waterfall/span-waterfall.js.map +1 -0
  967. package/dist/components/span-waterfall/span-waterfall.styles.d.ts +2 -0
  968. package/dist/components/span-waterfall/span-waterfall.styles.d.ts.map +1 -0
  969. package/dist/components/span-waterfall/span-waterfall.styles.js +130 -0
  970. package/dist/components/span-waterfall/span-waterfall.styles.js.map +1 -0
  971. package/dist/components/sparkline/sparkline.class.d.ts.map +1 -1
  972. package/dist/components/sparkline/sparkline.class.js +17 -7
  973. package/dist/components/sparkline/sparkline.class.js.map +1 -1
  974. package/dist/components/split/split.class.d.ts +13 -0
  975. package/dist/components/split/split.class.d.ts.map +1 -1
  976. package/dist/components/split/split.class.js +24 -4
  977. package/dist/components/split/split.class.js.map +1 -1
  978. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js +1 -1
  979. package/dist/components/spreadsheet-viewer/spreadsheet-loader.js.map +1 -1
  980. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts +93 -3
  981. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.d.ts.map +1 -1
  982. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js +241 -9
  983. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.class.js.map +1 -1
  984. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js +10 -1
  985. package/dist/components/spreadsheet-viewer/spreadsheet-viewer.js.map +1 -1
  986. package/dist/components/stack-trace/stack-trace-parse.d.ts +22 -0
  987. package/dist/components/stack-trace/stack-trace-parse.d.ts.map +1 -0
  988. package/dist/components/stack-trace/stack-trace-parse.js +194 -0
  989. package/dist/components/stack-trace/stack-trace-parse.js.map +1 -0
  990. package/dist/components/stack-trace/stack-trace.class.d.ts +68 -0
  991. package/dist/components/stack-trace/stack-trace.class.d.ts.map +1 -0
  992. package/dist/components/stack-trace/stack-trace.class.js +193 -0
  993. package/dist/components/stack-trace/stack-trace.class.js.map +1 -0
  994. package/dist/components/stack-trace/stack-trace.d.ts +3 -0
  995. package/dist/components/stack-trace/stack-trace.d.ts.map +1 -0
  996. package/dist/components/stack-trace/stack-trace.js +6 -0
  997. package/dist/components/stack-trace/stack-trace.js.map +1 -0
  998. package/dist/components/stack-trace/stack-trace.styles.d.ts +2 -0
  999. package/dist/components/stack-trace/stack-trace.styles.d.ts.map +1 -0
  1000. package/dist/components/stack-trace/stack-trace.styles.js +101 -0
  1001. package/dist/components/stack-trace/stack-trace.styles.js.map +1 -0
  1002. package/dist/components/stat/stat.class.d.ts +10 -1
  1003. package/dist/components/stat/stat.class.d.ts.map +1 -1
  1004. package/dist/components/stat/stat.class.js +22 -7
  1005. package/dist/components/stat/stat.class.js.map +1 -1
  1006. package/dist/components/stepper/stepper.class.d.ts +5 -0
  1007. package/dist/components/stepper/stepper.class.d.ts.map +1 -1
  1008. package/dist/components/stepper/stepper.class.js +9 -1
  1009. package/dist/components/stepper/stepper.class.js.map +1 -1
  1010. package/dist/components/stream-status/stream-status.class.d.ts.map +1 -1
  1011. package/dist/components/stream-status/stream-status.class.js +9 -1
  1012. package/dist/components/stream-status/stream-status.class.js.map +1 -1
  1013. package/dist/components/streaming-text/streaming-text.class.d.ts +6 -0
  1014. package/dist/components/streaming-text/streaming-text.class.d.ts.map +1 -1
  1015. package/dist/components/streaming-text/streaming-text.class.js +22 -3
  1016. package/dist/components/streaming-text/streaming-text.class.js.map +1 -1
  1017. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts +54 -0
  1018. package/dist/components/suggestion-chips/suggestion-chips.class.d.ts.map +1 -0
  1019. package/dist/components/suggestion-chips/suggestion-chips.class.js +120 -0
  1020. package/dist/components/suggestion-chips/suggestion-chips.class.js.map +1 -0
  1021. package/dist/components/suggestion-chips/suggestion-chips.d.ts +3 -0
  1022. package/dist/components/suggestion-chips/suggestion-chips.d.ts.map +1 -0
  1023. package/dist/components/suggestion-chips/suggestion-chips.js +6 -0
  1024. package/dist/components/suggestion-chips/suggestion-chips.js.map +1 -0
  1025. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts +2 -0
  1026. package/dist/components/suggestion-chips/suggestion-chips.styles.d.ts.map +1 -0
  1027. package/dist/components/suggestion-chips/suggestion-chips.styles.js +60 -0
  1028. package/dist/components/suggestion-chips/suggestion-chips.styles.js.map +1 -0
  1029. package/dist/components/svg-viewer/svg-viewer.class.d.ts +34 -0
  1030. package/dist/components/svg-viewer/svg-viewer.class.d.ts.map +1 -1
  1031. package/dist/components/svg-viewer/svg-viewer.class.js +88 -1
  1032. package/dist/components/svg-viewer/svg-viewer.class.js.map +1 -1
  1033. package/dist/components/svg-viewer/svg-viewer.js +1 -0
  1034. package/dist/components/svg-viewer/svg-viewer.js.map +1 -1
  1035. package/dist/components/svg-viewer/svg-viewer.styles.d.ts.map +1 -1
  1036. package/dist/components/svg-viewer/svg-viewer.styles.js +18 -0
  1037. package/dist/components/svg-viewer/svg-viewer.styles.js.map +1 -1
  1038. package/dist/components/swatch-picker/swatch-picker.class.d.ts +71 -0
  1039. package/dist/components/swatch-picker/swatch-picker.class.d.ts.map +1 -0
  1040. package/dist/components/swatch-picker/swatch-picker.class.js +134 -0
  1041. package/dist/components/swatch-picker/swatch-picker.class.js.map +1 -0
  1042. package/dist/components/swatch-picker/swatch-picker.d.ts +2 -0
  1043. package/dist/components/swatch-picker/swatch-picker.d.ts.map +1 -0
  1044. package/dist/components/swatch-picker/swatch-picker.js +5 -0
  1045. package/dist/components/swatch-picker/swatch-picker.js.map +1 -0
  1046. package/dist/components/swatch-picker/swatch-picker.styles.d.ts +2 -0
  1047. package/dist/components/swatch-picker/swatch-picker.styles.d.ts.map +1 -0
  1048. package/dist/components/swatch-picker/swatch-picker.styles.js +131 -0
  1049. package/dist/components/swatch-picker/swatch-picker.styles.js.map +1 -0
  1050. package/dist/components/table/table.class.d.ts +85 -5
  1051. package/dist/components/table/table.class.d.ts.map +1 -1
  1052. package/dist/components/table/table.class.js +254 -41
  1053. package/dist/components/table/table.class.js.map +1 -1
  1054. package/dist/components/table/table.styles.d.ts.map +1 -1
  1055. package/dist/components/table/table.styles.js +35 -0
  1056. package/dist/components/table/table.styles.js.map +1 -1
  1057. package/dist/components/tabs/tabs.class.d.ts +6 -0
  1058. package/dist/components/tabs/tabs.class.d.ts.map +1 -1
  1059. package/dist/components/tabs/tabs.class.js +10 -1
  1060. package/dist/components/tabs/tabs.class.js.map +1 -1
  1061. package/dist/components/tabs/tabs.styles.d.ts.map +1 -1
  1062. package/dist/components/tabs/tabs.styles.js +15 -0
  1063. package/dist/components/tabs/tabs.styles.js.map +1 -1
  1064. package/dist/components/task-list/task-list.class.d.ts +89 -0
  1065. package/dist/components/task-list/task-list.class.d.ts.map +1 -0
  1066. package/dist/components/task-list/task-list.class.js +271 -0
  1067. package/dist/components/task-list/task-list.class.js.map +1 -0
  1068. package/dist/components/task-list/task-list.d.ts +2 -0
  1069. package/dist/components/task-list/task-list.d.ts.map +1 -0
  1070. package/dist/components/task-list/task-list.js +5 -0
  1071. package/dist/components/task-list/task-list.js.map +1 -0
  1072. package/dist/components/task-list/task-list.styles.d.ts +2 -0
  1073. package/dist/components/task-list/task-list.styles.d.ts.map +1 -0
  1074. package/dist/components/task-list/task-list.styles.js +134 -0
  1075. package/dist/components/task-list/task-list.styles.js.map +1 -0
  1076. package/dist/components/terminal/terminal.class.d.ts +150 -0
  1077. package/dist/components/terminal/terminal.class.d.ts.map +1 -0
  1078. package/dist/components/terminal/terminal.class.js +565 -0
  1079. package/dist/components/terminal/terminal.class.js.map +1 -0
  1080. package/dist/components/terminal/terminal.d.ts +2 -0
  1081. package/dist/components/terminal/terminal.d.ts.map +1 -0
  1082. package/dist/components/terminal/terminal.js +5 -0
  1083. package/dist/components/terminal/terminal.js.map +1 -0
  1084. package/dist/components/terminal/terminal.styles.d.ts +2 -0
  1085. package/dist/components/terminal/terminal.styles.d.ts.map +1 -0
  1086. package/dist/components/terminal/terminal.styles.js +77 -0
  1087. package/dist/components/terminal/terminal.styles.js.map +1 -0
  1088. package/dist/components/test-results/test-results.class.d.ts +99 -0
  1089. package/dist/components/test-results/test-results.class.d.ts.map +1 -0
  1090. package/dist/components/test-results/test-results.class.js +276 -0
  1091. package/dist/components/test-results/test-results.class.js.map +1 -0
  1092. package/dist/components/test-results/test-results.d.ts +2 -0
  1093. package/dist/components/test-results/test-results.d.ts.map +1 -0
  1094. package/dist/components/test-results/test-results.js +5 -0
  1095. package/dist/components/test-results/test-results.js.map +1 -0
  1096. package/dist/components/test-results/test-results.styles.d.ts +2 -0
  1097. package/dist/components/test-results/test-results.styles.d.ts.map +1 -0
  1098. package/dist/components/test-results/test-results.styles.js +118 -0
  1099. package/dist/components/test-results/test-results.styles.js.map +1 -0
  1100. package/dist/components/textarea/textarea.class.d.ts.map +1 -1
  1101. package/dist/components/textarea/textarea.class.js +4 -0
  1102. package/dist/components/textarea/textarea.class.js.map +1 -1
  1103. package/dist/components/thinking-panel/thinking-panel.class.d.ts +6 -0
  1104. package/dist/components/thinking-panel/thinking-panel.class.d.ts.map +1 -1
  1105. package/dist/components/thinking-panel/thinking-panel.class.js +12 -2
  1106. package/dist/components/thinking-panel/thinking-panel.class.js.map +1 -1
  1107. package/dist/components/thread-list/thread-list.class.d.ts +130 -0
  1108. package/dist/components/thread-list/thread-list.class.d.ts.map +1 -0
  1109. package/dist/components/thread-list/thread-list.class.js +480 -0
  1110. package/dist/components/thread-list/thread-list.class.js.map +1 -0
  1111. package/dist/components/thread-list/thread-list.d.ts +5 -0
  1112. package/dist/components/thread-list/thread-list.d.ts.map +1 -0
  1113. package/dist/components/thread-list/thread-list.js +8 -0
  1114. package/dist/components/thread-list/thread-list.js.map +1 -0
  1115. package/dist/components/thread-list/thread-list.styles.d.ts +2 -0
  1116. package/dist/components/thread-list/thread-list.styles.d.ts.map +1 -0
  1117. package/dist/components/thread-list/thread-list.styles.js +81 -0
  1118. package/dist/components/thread-list/thread-list.styles.js.map +1 -0
  1119. package/dist/components/time-range/time-range.class.d.ts.map +1 -1
  1120. package/dist/components/time-range/time-range.class.js +3 -3
  1121. package/dist/components/time-range/time-range.class.js.map +1 -1
  1122. package/dist/components/timeline/timeline-item.class.d.ts.map +1 -1
  1123. package/dist/components/timeline/timeline-item.class.js +2 -1
  1124. package/dist/components/timeline/timeline-item.class.js.map +1 -1
  1125. package/dist/components/toast/toast-item.class.d.ts +8 -0
  1126. package/dist/components/toast/toast-item.class.d.ts.map +1 -1
  1127. package/dist/components/toast/toast-item.class.js +14 -2
  1128. package/dist/components/toast/toast-item.class.js.map +1 -1
  1129. package/dist/components/toast/toast-item.styles.d.ts.map +1 -1
  1130. package/dist/components/toast/toast-item.styles.js +2 -0
  1131. package/dist/components/toast/toast-item.styles.js.map +1 -1
  1132. package/dist/components/token-input/token-input.class.d.ts +29 -3
  1133. package/dist/components/token-input/token-input.class.d.ts.map +1 -1
  1134. package/dist/components/token-input/token-input.class.js +41 -13
  1135. package/dist/components/token-input/token-input.class.js.map +1 -1
  1136. package/dist/components/token-input/token-input.styles.d.ts.map +1 -1
  1137. package/dist/components/token-input/token-input.styles.js +6 -1
  1138. package/dist/components/token-input/token-input.styles.js.map +1 -1
  1139. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts +6 -0
  1140. package/dist/components/tool-call-chip/tool-call-chip.class.d.ts.map +1 -1
  1141. package/dist/components/tool-call-chip/tool-call-chip.class.js +15 -4
  1142. package/dist/components/tool-call-chip/tool-call-chip.class.js.map +1 -1
  1143. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts +6 -0
  1144. package/dist/components/tool-result-dialog/tool-result-dialog.class.d.ts.map +1 -1
  1145. package/dist/components/tool-result-dialog/tool-result-dialog.class.js +12 -3
  1146. package/dist/components/tool-result-dialog/tool-result-dialog.class.js.map +1 -1
  1147. package/dist/components/tour/tour.class.d.ts +6 -3
  1148. package/dist/components/tour/tour.class.d.ts.map +1 -1
  1149. package/dist/components/tour/tour.class.js +56 -20
  1150. package/dist/components/tour/tour.class.js.map +1 -1
  1151. package/dist/components/trace-tree/span.d.ts +26 -0
  1152. package/dist/components/trace-tree/span.d.ts.map +1 -0
  1153. package/dist/components/trace-tree/span.js +2 -0
  1154. package/dist/components/trace-tree/span.js.map +1 -0
  1155. package/dist/components/trace-tree/trace-tree.class.d.ts +85 -0
  1156. package/dist/components/trace-tree/trace-tree.class.d.ts.map +1 -0
  1157. package/dist/components/trace-tree/trace-tree.class.js +443 -0
  1158. package/dist/components/trace-tree/trace-tree.class.js.map +1 -0
  1159. package/dist/components/trace-tree/trace-tree.d.ts +5 -0
  1160. package/dist/components/trace-tree/trace-tree.d.ts.map +1 -0
  1161. package/dist/components/trace-tree/trace-tree.js +8 -0
  1162. package/dist/components/trace-tree/trace-tree.js.map +1 -0
  1163. package/dist/components/trace-tree/trace-tree.styles.d.ts +2 -0
  1164. package/dist/components/trace-tree/trace-tree.styles.d.ts.map +1 -0
  1165. package/dist/components/trace-tree/trace-tree.styles.js +186 -0
  1166. package/dist/components/trace-tree/trace-tree.styles.js.map +1 -0
  1167. package/dist/components/transcript-feed/transcript-feed.class.d.ts +89 -0
  1168. package/dist/components/transcript-feed/transcript-feed.class.d.ts.map +1 -0
  1169. package/dist/components/transcript-feed/transcript-feed.class.js +188 -0
  1170. package/dist/components/transcript-feed/transcript-feed.class.js.map +1 -0
  1171. package/dist/components/transcript-feed/transcript-feed.d.ts +2 -0
  1172. package/dist/components/transcript-feed/transcript-feed.d.ts.map +1 -0
  1173. package/dist/components/transcript-feed/transcript-feed.js +5 -0
  1174. package/dist/components/transcript-feed/transcript-feed.js.map +1 -0
  1175. package/dist/components/transcript-feed/transcript-feed.styles.d.ts +2 -0
  1176. package/dist/components/transcript-feed/transcript-feed.styles.d.ts.map +1 -0
  1177. package/dist/components/transcript-feed/transcript-feed.styles.js +94 -0
  1178. package/dist/components/transcript-feed/transcript-feed.styles.js.map +1 -0
  1179. package/dist/components/tree/tree-node.class.d.ts +25 -4
  1180. package/dist/components/tree/tree-node.class.d.ts.map +1 -1
  1181. package/dist/components/tree/tree-node.class.js +61 -11
  1182. package/dist/components/tree/tree-node.class.js.map +1 -1
  1183. package/dist/components/tree/tree-node.styles.d.ts.map +1 -1
  1184. package/dist/components/tree/tree-node.styles.js +34 -5
  1185. package/dist/components/tree/tree-node.styles.js.map +1 -1
  1186. package/dist/components/tree/tree.class.d.ts +9 -0
  1187. package/dist/components/tree/tree.class.d.ts.map +1 -1
  1188. package/dist/components/tree/tree.class.js.map +1 -1
  1189. package/dist/components/usage-badge/usage-badge.class.d.ts +78 -0
  1190. package/dist/components/usage-badge/usage-badge.class.d.ts.map +1 -0
  1191. package/dist/components/usage-badge/usage-badge.class.js +237 -0
  1192. package/dist/components/usage-badge/usage-badge.class.js.map +1 -0
  1193. package/dist/components/usage-badge/usage-badge.d.ts +2 -0
  1194. package/dist/components/usage-badge/usage-badge.d.ts.map +1 -0
  1195. package/dist/components/usage-badge/usage-badge.js +5 -0
  1196. package/dist/components/usage-badge/usage-badge.js.map +1 -0
  1197. package/dist/components/usage-badge/usage-badge.styles.d.ts +2 -0
  1198. package/dist/components/usage-badge/usage-badge.styles.d.ts.map +1 -0
  1199. package/dist/components/usage-badge/usage-badge.styles.js +62 -0
  1200. package/dist/components/usage-badge/usage-badge.styles.js.map +1 -0
  1201. package/dist/components/virtual-list/virtual-list.class.d.ts +62 -0
  1202. package/dist/components/virtual-list/virtual-list.class.d.ts.map +1 -1
  1203. package/dist/components/virtual-list/virtual-list.class.js +123 -8
  1204. package/dist/components/virtual-list/virtual-list.class.js.map +1 -1
  1205. package/dist/components/voice-picker/voice-picker.class.d.ts +241 -0
  1206. package/dist/components/voice-picker/voice-picker.class.d.ts.map +1 -0
  1207. package/dist/components/voice-picker/voice-picker.class.js +808 -0
  1208. package/dist/components/voice-picker/voice-picker.class.js.map +1 -0
  1209. package/dist/components/voice-picker/voice-picker.d.ts +2 -0
  1210. package/dist/components/voice-picker/voice-picker.d.ts.map +1 -0
  1211. package/dist/components/voice-picker/voice-picker.js +5 -0
  1212. package/dist/components/voice-picker/voice-picker.js.map +1 -0
  1213. package/dist/components/voice-picker/voice-picker.styles.d.ts +2 -0
  1214. package/dist/components/voice-picker/voice-picker.styles.d.ts.map +1 -0
  1215. package/dist/components/voice-picker/voice-picker.styles.js +272 -0
  1216. package/dist/components/voice-picker/voice-picker.styles.js.map +1 -0
  1217. package/dist/components/widget-renderer/default-registry.d.ts +14 -0
  1218. package/dist/components/widget-renderer/default-registry.d.ts.map +1 -0
  1219. package/dist/components/widget-renderer/default-registry.js +43 -0
  1220. package/dist/components/widget-renderer/default-registry.js.map +1 -0
  1221. package/dist/components/widget-renderer/registry.d.ts +31 -0
  1222. package/dist/components/widget-renderer/registry.d.ts.map +1 -0
  1223. package/dist/components/widget-renderer/registry.js +23 -0
  1224. package/dist/components/widget-renderer/registry.js.map +1 -0
  1225. package/dist/components/widget-renderer/resolve.d.ts +48 -0
  1226. package/dist/components/widget-renderer/resolve.d.ts.map +1 -0
  1227. package/dist/components/widget-renderer/resolve.js +122 -0
  1228. package/dist/components/widget-renderer/resolve.js.map +1 -0
  1229. package/dist/components/widget-renderer/widget-renderer.class.d.ts +67 -0
  1230. package/dist/components/widget-renderer/widget-renderer.class.d.ts.map +1 -0
  1231. package/dist/components/widget-renderer/widget-renderer.class.js +175 -0
  1232. package/dist/components/widget-renderer/widget-renderer.class.js.map +1 -0
  1233. package/dist/components/widget-renderer/widget-renderer.d.ts +5 -0
  1234. package/dist/components/widget-renderer/widget-renderer.d.ts.map +1 -0
  1235. package/dist/components/widget-renderer/widget-renderer.js +10 -0
  1236. package/dist/components/widget-renderer/widget-renderer.js.map +1 -0
  1237. package/dist/components/widget-renderer/widget-renderer.styles.d.ts +2 -0
  1238. package/dist/components/widget-renderer/widget-renderer.styles.d.ts.map +1 -0
  1239. package/dist/components/widget-renderer/widget-renderer.styles.js +14 -0
  1240. package/dist/components/widget-renderer/widget-renderer.styles.js.map +1 -0
  1241. package/dist/components/word-cloud/word-cloud-layout.d.ts +4 -0
  1242. package/dist/components/word-cloud/word-cloud-layout.d.ts.map +1 -1
  1243. package/dist/components/word-cloud/word-cloud-layout.js +3 -2
  1244. package/dist/components/word-cloud/word-cloud-layout.js.map +1 -1
  1245. package/dist/components/word-cloud/word-cloud.class.d.ts.map +1 -1
  1246. package/dist/components/word-cloud/word-cloud.class.js +11 -3
  1247. package/dist/components/word-cloud/word-cloud.class.js.map +1 -1
  1248. package/dist/components/xml-viewer/xml-viewer.class.d.ts +135 -0
  1249. package/dist/components/xml-viewer/xml-viewer.class.d.ts.map +1 -0
  1250. package/dist/components/xml-viewer/xml-viewer.class.js +0 -0
  1251. package/dist/components/xml-viewer/xml-viewer.class.js.map +1 -0
  1252. package/dist/components/xml-viewer/xml-viewer.d.ts +2 -0
  1253. package/dist/components/xml-viewer/xml-viewer.d.ts.map +1 -0
  1254. package/dist/components/xml-viewer/xml-viewer.js +20 -0
  1255. package/dist/components/xml-viewer/xml-viewer.js.map +1 -0
  1256. package/dist/components/xml-viewer/xml-viewer.styles.d.ts +2 -0
  1257. package/dist/components/xml-viewer/xml-viewer.styles.d.ts.map +1 -0
  1258. package/dist/components/xml-viewer/xml-viewer.styles.js +156 -0
  1259. package/dist/components/xml-viewer/xml-viewer.styles.js.map +1 -0
  1260. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts +14 -2
  1261. package/dist/components/zoomable-frame/zoomable-frame.class.d.ts.map +1 -1
  1262. package/dist/components/zoomable-frame/zoomable-frame.class.js +30 -14
  1263. package/dist/components/zoomable-frame/zoomable-frame.class.js.map +1 -1
  1264. package/dist/internal/anchor-target.d.ts +49 -0
  1265. package/dist/internal/anchor-target.d.ts.map +1 -0
  1266. package/dist/internal/anchor-target.js +255 -0
  1267. package/dist/internal/anchor-target.js.map +1 -0
  1268. package/dist/internal/ansi.d.ts +35 -0
  1269. package/dist/internal/ansi.d.ts.map +1 -0
  1270. package/dist/internal/ansi.js +210 -0
  1271. package/dist/internal/ansi.js.map +1 -0
  1272. package/dist/internal/cell-range.d.ts +19 -0
  1273. package/dist/internal/cell-range.d.ts.map +1 -0
  1274. package/dist/internal/cell-range.js +69 -0
  1275. package/dist/internal/cell-range.js.map +1 -0
  1276. package/dist/internal/intl-cache.d.ts +33 -0
  1277. package/dist/internal/intl-cache.d.ts.map +1 -0
  1278. package/dist/internal/intl-cache.js +0 -0
  1279. package/dist/internal/intl-cache.js.map +1 -0
  1280. package/dist/internal/layered-layout.d.ts +44 -0
  1281. package/dist/internal/layered-layout.d.ts.map +1 -0
  1282. package/dist/internal/layered-layout.js +172 -0
  1283. package/dist/internal/layered-layout.js.map +1 -0
  1284. package/dist/internal/localization.d.ts +12 -1
  1285. package/dist/internal/localization.d.ts.map +1 -1
  1286. package/dist/internal/localization.js +367 -4
  1287. package/dist/internal/localization.js.map +1 -1
  1288. package/dist/internal/lyra-element.d.ts +10 -1
  1289. package/dist/internal/lyra-element.d.ts.map +1 -1
  1290. package/dist/internal/lyra-element.js +19 -1
  1291. package/dist/internal/lyra-element.js.map +1 -1
  1292. package/dist/internal/root-registration-allowlist.d.ts +2 -2
  1293. package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
  1294. package/dist/internal/root-registration-allowlist.js +55 -0
  1295. package/dist/internal/root-registration-allowlist.js.map +1 -1
  1296. package/dist/internal/slugger.d.ts +11 -0
  1297. package/dist/internal/slugger.d.ts.map +1 -0
  1298. package/dist/internal/slugger.js +45 -0
  1299. package/dist/internal/slugger.js.map +1 -0
  1300. package/dist/internal/text-highlights.d.ts +21 -0
  1301. package/dist/internal/text-highlights.d.ts.map +1 -0
  1302. package/dist/internal/text-highlights.js +172 -0
  1303. package/dist/internal/text-highlights.js.map +1 -0
  1304. package/dist/internal/text-quote.d.ts +53 -0
  1305. package/dist/internal/text-quote.d.ts.map +1 -0
  1306. package/dist/internal/text-quote.js +326 -0
  1307. package/dist/internal/text-quote.js.map +1 -0
  1308. package/dist/internal/tokens.styles.d.ts.map +1 -1
  1309. package/dist/internal/tokens.styles.js +49 -0
  1310. package/dist/internal/tokens.styles.js.map +1 -1
  1311. package/dist/internal/viewer-search.d.ts +18 -0
  1312. package/dist/internal/viewer-search.d.ts.map +1 -0
  1313. package/dist/internal/viewer-search.js +21 -0
  1314. package/dist/internal/viewer-search.js.map +1 -0
  1315. package/dist/lyra.d.ts +137 -2
  1316. package/dist/lyra.d.ts.map +1 -1
  1317. package/dist/lyra.js +109 -0
  1318. package/dist/lyra.js.map +1 -1
  1319. package/llms-full.txt +2682 -78
  1320. package/llms.txt +28 -2
  1321. package/package.json +157 -31
  1322. package/vscode-css-data.json +231 -0
  1323. package/vscode-html-data.json +5222 -2201
  1324. package/web-types.json +5721 -2508
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
  ---
@@ -740,10 +740,15 @@ shadow-internal native button doesn't participate in an ancestor form's submissi
740
740
 
741
741
  **Properties:**
742
742
  - `variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' = 'neutral'` (reflected)
743
- - `appearance: 'accent' | 'filled' | 'outlined' | 'plain' = 'filled'` (reflected) — `'accent'` is a
743
+ - `appearance: 'accent' | 'filled' | 'outlined' | 'plain' | 'link' = 'filled'` (reflected) —
744
+ `'accent'` is a
744
745
  loud, high-contrast filled tier,
745
746
  distinct from `'filled'` for `variant="neutral"` specifically (`'filled'` reads the ambient
746
- surface color there; `'accent'` reads a solid neutral fill)
747
+ surface color there; `'accent'` reads a solid neutral fill). `'link'` is a true inline-link tier:
748
+ zero chrome (no padding, border, border-radius, or `min-block-size` floor), underlined
749
+ (`text-underline-offset: var(--lyra-size-0-15rem)`), colored from `--lyra-button-accent` (the same token `'plain'`
750
+ uses, so `variant` still selects the link color) and inheriting the surrounding font-size/weight
751
+ — for a text link that flows within a sentence rather than a button-shaped control
747
752
  - `size: 'xs' | 's' | 'm' | 'l' | 'xl' = 'm'` (reflected)
748
753
  - `type: 'button' | 'submit' | 'reset' = 'button'`
749
754
  - `loading: boolean = false` (reflected) — shows an internal spinner and disables the button without
@@ -779,6 +784,7 @@ loud fill token), `--lyra-button-hover-brightness` (default `1.08`, the `:hover`
779
784
  <lyra-button variant="brand" appearance="filled">Save</lyra-button>
780
785
  <lyra-button variant="neutral" appearance="accent">Save</lyra-button>
781
786
  <lyra-button appearance="plain" aria-label="Close dialog"><svg slot="start">...</svg></lyra-button>
787
+ <p>The message failed. <lyra-button appearance="link" variant="brand">Retry</lyra-button></p>
782
788
  ```
783
789
 
784
790
  **Known gotchas:**
@@ -1447,12 +1453,17 @@ accent edge and value tint).
1447
1453
  ## `lyra-table`
1448
1454
 
1449
1455
  Sort/select-aware data table. Sorting remains consumer-controlled; optional filtering, pagination,
1450
- 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.
1451
1462
 
1452
1463
  **Properties:**
1453
1464
  - `columns: TableColumn<T>[] = []` (attribute: false) — `{ key, label, headerCell?, width?,
1454
- minWidth?, sortable?, align?: 'start'|'end', priority?: 'medium'|'low', sticky?: boolean |
1455
- '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 }` —
1456
1467
  `priority` progressively hides that column via a `@container` query as `[part='base']` narrows
1457
1468
  (`'low'` hides first, under a ~900px container width; `'medium'` next, under ~640px; both
1458
1469
  breakpoints are fixed in `table.styles.ts`, not themeable tokens), reversible via
@@ -1463,10 +1474,17 @@ and loading chrome are built in while remaining controlled at the public API bou
1463
1474
  sticky-bottom footer cell for that column, computed from every currently-rendered row (post-sort,
1464
1475
  pre-pagination) — e.g. a column total — omit it for a column with no footer value, and a
1465
1476
  `[part='foot']` (`<tfoot>`) only renders at all when at least one column defines `footer`;
1466
- `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
1467
1483
  background a `cell()`-returned inner element can't paint into the cell's own padding — omit it for
1468
1484
  no per-cell style override (the default, unchanged output); `editable` enables double-click
1469
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.
1470
1488
  - `columnsHidden: boolean = false` (attribute `columns-hidden`, reflected) — computed/read-only: true
1471
1489
  when a `priority` column is *actually* hidden right now by the `@container` breakpoints above, or
1472
1490
  `showAllColumns` force-visible mode is currently active. Measured via a `ResizeObserver` on
@@ -1532,6 +1550,19 @@ and loading chrome are built in while remaining controlled at the public API bou
1532
1550
  button's label once they've been revealed)
1533
1551
  - `showAllColumns: boolean = false` (attribute `show-all-columns`, reflected) — forces responsive
1534
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
1535
1566
 
1536
1567
  **Events:** `lyra-sort` (`detail: { key }`, fired on sortable-header activation), `lyra-row-click`
1537
1568
  (`detail: { row }`), `lyra-load-more` (fired on the "load more" button), `lyra-columns-hidden-change`
@@ -1541,19 +1572,26 @@ and loading chrome are built in while remaining controlled at the public API bou
1541
1572
  `lyra-selection-change` (`detail: { keys }`) when selection is enabled, `lyra-filter-change`
1542
1573
  (`detail: { text }`), and `lyra-page-change` (`detail: { page }`) from the controlled
1543
1574
  filter/pagination surfaces, and `lyra-cell-edit` (`detail: { row, key, value }`) for editable
1544
- columns
1575
+ columns, and `lyra-column-resize` (`detail: { key, width }`) on every resize drag step
1545
1576
 
1546
1577
  **Slots:** none — content comes entirely from `columns`/`rows`.
1547
1578
 
1548
1579
  **CSS parts:** `base`, `table`, `head`, `header-cell`, `row`, `cell`, `more-button`, `sort-icon` (a
1549
1580
  chevron indicator shown on the active sortable header, rotated per `sortDir`), `reveal-columns-button`
1550
1581
  (shown only when `columnsHidden` is true), `foot` (the `<tfoot>`, only rendered when at least one
1551
- 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`,
1552
1586
  `row-expand-icon`, `expanded-row`, `expanded-cell`, `filter-label`, `filter`, `loading`, and
1553
- `pagination`, `cell-editor`, `group-row`, and `group-cell`
1587
+ `pagination`, `cell-editor`, `group-row`, `group-cell`, and `resize-handle`
1554
1588
 
1555
1589
  **Themeable custom properties:** `--lyra-table-max-height` (default `none`; controls the scrollable
1556
- 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.
1557
1595
 
1558
1596
  **Optional peer deps:** none.
1559
1597
 
@@ -2501,16 +2539,95 @@ same color as `--lyra-heatmap-focus-ring-color`).
2501
2539
 
2502
2540
  ---
2503
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
+
2504
2609
  ## `lyra-graph`
2505
2610
 
2506
2611
  A force-directed node-link diagram with pan/zoom/drag, built on `d3-force`.
2507
2612
 
2508
2613
  **Properties:**
2509
2614
  - `nodes: GraphNode[] = []` (attribute: false) — `GraphNode { id: string; label?: string;
2510
- accessibleLabel?: string; description?: string; radius?: number; color?: string }`;
2615
+ accessibleLabel?: string; description?: string; radius?: number; color?: string; type?: string }`;
2511
2616
  `accessibleLabel` supplies richer spoken text than the visible label, while `description` renders
2512
2617
  as native SVG `<title>` tooltip text. `radius` is clamped to `[6, 24]` (an unset/non-finite value
2513
- 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
2514
2631
  - `links: GraphLink[] = []` (attribute: false) — `GraphLink { id?: string; source: string; target:
2515
2632
  string; width?: number; label?: string; accessibleLabel?: string; description?: string; directed?:
2516
2633
  boolean; color?: string; dash?: number[] }` (source/target are node ids). `directed` adds an
@@ -2535,19 +2652,65 @@ A force-directed node-link diagram with pan/zoom/drag, built on `d3-force`.
2535
2652
  (keyed by node **id**, not array index/order) instead of `forceSimulation()`'s own random start,
2536
2653
  and settles the simulation synchronously instead of animating the settle (same effect
2537
2654
  `prefers-reduced-motion` has, see gotchas)
2538
-
2539
- **Events:** `lyra-node-click` (`detail: { id }`), `lyra-link-click` (`detail: { source, target,
2540
- 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)
2541
2694
 
2542
2695
  **Slots:** none.
2543
2696
 
2544
2697
  **CSS parts:** `base`, `svg`, `node`, `link`, `arrowhead` (the marker path shared by directed links),
2545
- `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)
2546
2704
 
2547
2705
  **Themeable custom properties:** `--lyra-node-fill` (set inline per-node from `GraphNode.color`,
2548
2706
  falls back to `--lyra-color-brand`) and `--lyra-link-color` (set inline per-link from
2549
2707
  `GraphLink.color`, falling back to `--lyra-color-border`); also uses `--lyra-color-text` +
2550
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`).
2551
2714
 
2552
2715
  **Optional peer deps:** `d3-force`, `d3-drag`, `d3-zoom`, `d3-selection` (all four required
2553
2716
  together; lazy-`import()`ed once per page, `console.warn` once and renders empty if missing —
@@ -2610,6 +2773,26 @@ install with `pnpm add d3-force d3-drag d3-zoom d3-selection`).
2610
2773
  - the `<svg part="svg">` now carries `role="group"` and an `aria-label` summarizing the node/link
2611
2774
  counts (e.g. "Node-link diagram with 5 nodes and 4 links"), and node `<text part="label">`s are
2612
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.
2613
2796
 
2614
2797
  ---
2615
2798
 
@@ -2734,6 +2917,816 @@ indentation), plus the shared tokens listed above.
2734
2917
 
2735
2918
  ---
2736
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).
3702
+
3703
+ **Themeable custom properties:** `--lyra-mind-map-ring-gap` (default `6rem`, radius step per depth
3704
+ ring).
3705
+
3706
+ **Optional peer deps:** none.
3707
+
3708
+ ```html
3709
+ <lyra-mind-map style="height:480px" expand-depth="2"></lyra-mind-map>
3710
+ <script>
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
+ ] },
3716
+ ];
3717
+ </script>
3718
+ ```
3719
+
3720
+ **Known gotchas:**
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.
3727
+
3728
+ ---
3729
+
2737
3730
  # Chart family (`chart/`)
2738
3731
 
2739
3732
  ## `lyra-chart` (core)
@@ -2753,6 +3746,12 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2753
3746
  noTooltip?: boolean; axis?: 'y'|'y2'; pointColors?: string[]; pointRadius?: number; type?:
2754
3747
  'line'|'bar' }`
2755
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
2756
3755
  - `area: boolean = false`
2757
3756
  - `zoom: boolean = false`
2758
3757
  - `height: string = '280px'`
@@ -2774,6 +3773,9 @@ Chart.js wrapper every other `lyra-*-chart` tag subclasses; supports both a simp
2774
3773
  localized data/trend summary
2775
3774
  - `showDataTable: boolean = false` (attribute `show-data-table`) — makes the always-available
2776
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
2777
3779
 
2778
3780
  **Methods:** `resetZoom()` (reset any active zoom/pan to the original view), `refreshTheme()`
2779
3781
  (forces a redraw so the `--lyra-chart-*` tokens below are re-read from the current computed style —
@@ -2785,9 +3787,11 @@ the escape hatch for a consumer's own theme-toggle handler to call when it flips
2785
3787
  a data point/segment, for any chart type, not just bar; `detail: { datasetIndex: number, index:
2786
3788
  number, label: string | undefined, value: unknown }`)
2787
3789
 
2788
- **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.
2789
3792
 
2790
- **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)
2791
3795
 
2792
3796
  **Themeable custom properties:** `--lyra-chart-height` (set programmatically on the host from the
2793
3797
  `height` property — must be read from the host, not a shadow-tree descendant, since custom
@@ -2902,6 +3906,10 @@ passthrough). Not a subclass of `LyraChart`.
2902
3906
  - `pointText?: (label: string, value: number, datasetIndex: number) => string` (attribute: false) —
2903
3907
  overrides the per-bar/per-point `<title>`/`aria-label` tooltip text (mirrors `lyra-heatmap`'s
2904
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`.
2905
3913
  - `roundedBars: boolean = false` (attribute `rounded-bars`, bar type only) — draws each bar as a
2906
3914
  rounded-top-corner shape instead of a square-cornered `<rect>`.
2907
3915
  - `skipZero: boolean = false` (attribute `skip-zero`, bar type only) — omits a bar entirely (no
@@ -2944,8 +3952,9 @@ fresh, small SVG render is cheaper and more correct than a lossy cache.
2944
3952
 
2945
3953
  **CSS parts:** `base`, `grid-line`, `axis-label`, `axis-title`, `bar` (each bar rect; carries
2946
3954
  `data-selected` when its category index is in `selectedIndex`), `line`, `point`, `legend`,
2947
- `legend-item`, `legend-swatch`, `live-region` (the current mark announcement for keyboard users),
2948
- `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).
2949
3958
 
2950
3959
  **Themeable custom properties:** `--lyra-chart-height` (same host-level property as `lyra-chart`);
2951
3960
  `--lyra-chart-grid-color`, `--lyra-chart-tick-color`, `--lyra-chart-legend-color` — same token
@@ -3105,8 +4114,8 @@ independently of the base `chart-loader.ts`).
3105
4114
 
3106
4115
  ## `lyra-map`
3107
4116
 
3108
- A `maplibre-gl` wrapper with a declarative legend and a single choropleth GeoJSON fill layer, plus a
3109
- 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.
3110
4119
 
3111
4120
  **Properties:**
3112
4121
  - `center: [number, number] = [0, 0]`
@@ -3131,6 +4140,17 @@ raw `map` escape hatch for anything unexposed.
3131
4140
  escaped) when the content is plain text. A marker whose `color` changes for a persisting `id`
3132
4141
  can't be recolored in place (no `Marker.setColor()`) and is torn down/reconstructed instead — see
3133
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.
3134
4154
  - `label: string = ''` — accessible name for the map region, applied as `[part="base"]`'s
3135
4155
  `aria-label`. A plain `aria-label` attribute on the host itself is honored as a fallback when
3136
4156
  `label` is left unset, matching `lyra-slider`/`lyra-checkbox`/`lyra-switch`; with neither set, it
@@ -3175,9 +4195,9 @@ exists and was hit)
3175
4195
  `removeSource` on whatever was previously applied before adding the new one (or nothing, if
3176
4196
  cleared).
3177
4197
  - `mapStyle` changes after construction now call `setStyle()` (in addition to `center`/`zoom`
3178
- already calling `setCenter`/`setZoom`) — the choropleth is automatically re-applied once the new
3179
- style's own `'style.load'` fires, since a style change wipes every layer/source maplibre-gl knows
3180
- 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.
3181
4201
  - Point markers now have a declarative API (`markers`, above) with popup support — the `.map` escape
3182
4202
  hatch and manual `new maplibregl.Marker()` are no longer the only way to place pins.
3183
4203
  - a marker whose `color` changes for a persisting `id` is torn down and reconstructed (maplibre-gl's
@@ -3698,6 +4718,9 @@ wrapper at all, so existing text-only tabs are unaffected.
3698
4718
  - `active: string = ''` (reflected) — the active tab's `slot`/id; falls back to the first enabled
3699
4719
  tab whenever the current value doesn't resolve to one (including on every children/attribute
3700
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).
3701
4724
 
3702
4725
  **Events:** `lyra-tabs-change` (`detail: { tabId: string }`) — fired when the active tab changes via
3703
4726
  click or keyboard. Not fired when `active` self-corrects to a valid tab (initial default, or a tab
@@ -3760,6 +4783,9 @@ convention).
3760
4783
  - `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected) — `'horizontal'` (the default)
3761
4784
  lays steps out in a row (Left/Right, RTL-aware, navigate); `'vertical'` stacks them (Up/Down
3762
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).
3763
4789
 
3764
4790
  **Events:** `lyra-step-select` (`detail: { index, id }`) — fired on click, or Enter/Space while
3765
4791
  focused, on a non-`disabled` step. Cancelable, though this component takes no default action of its
@@ -3860,6 +4886,66 @@ keyboard.
3860
4886
 
3861
4887
  ---
3862
4888
 
4889
+ ## `lyra-swatch-picker`
4890
+
4891
+ A single-select picker over a small, fixed set of color swatches with the WAI-ARIA APG
4892
+ `radiogroup` contract built in: `role="radiogroup"`/`role="radio"`, roving tabindex, automatic
4893
+ activation (click or arrow-key move both select immediately, like a native radio group), cyclic
4894
+ Arrow/Home/End navigation. First-party invention (no Web Awesome equivalent). Distinct from
4895
+ `lyra-color-picker`'s freeform native color input — this picks exactly one of N designer-chosen
4896
+ named colors, the shape apps otherwise hand-roll as a row of round accent-color buttons.
4897
+
4898
+ **Properties:**
4899
+ - `options: SwatchOption[] = []` (attribute: false) — `SwatchOption { value: string; color: string;
4900
+ label: string }`; `color` is any CSS color string used as the swatch fill, `label` is each
4901
+ swatch's accessible name and `title`.
4902
+ - `value: string | null = null` — the currently selected option's `value` (controlled); `null`
4903
+ leaves nothing selected while keeping the first swatch tabbable.
4904
+ - `label: string = ''` — accessible name copied to the internal `role="radiogroup"`; when empty, a
4905
+ host-level `aria-label` is used as a fallback.
4906
+
4907
+ **Events:** `lyra-change` (`detail: { value }`) — fired only when the selected value actually
4908
+ changes via click or keyboard (re-selecting the current swatch is a no-op).
4909
+
4910
+ **Slots:** none.
4911
+
4912
+ **CSS parts:** `base` (the `role="radiogroup"` root), `swatch` (a single `role="radio"` color
4913
+ swatch; the selected one is `[part='swatch'][aria-checked='true']`).
4914
+
4915
+ **Themeable custom properties:** `--lyra-swatch-picker-selected-color` (ring color around the
4916
+ selected swatch, defaults to `--lyra-color-brand`, themeable independently of the focus ring); plus
4917
+ shared tokens — `--lyra-color-border`/`-brand`, `--lyra-space-xs`, `--lyra-size-1-5rem`,
4918
+ `--lyra-border-width-thin`/`-thick`, `--lyra-radius`, `--lyra-transition-fast`,
4919
+ `--lyra-focus-ring-*`.
4920
+
4921
+ **Optional peer deps:** none.
4922
+
4923
+ ```html
4924
+ <lyra-swatch-picker label="Accent color"></lyra-swatch-picker>
4925
+ <script type="module">
4926
+ const picker = document.querySelector('lyra-swatch-picker');
4927
+ picker.options = [
4928
+ { value: 'blue', color: '#0969da', label: 'Blue' },
4929
+ { value: 'green', color: '#1a7f37', label: 'Green' },
4930
+ { value: 'purple', color: '#8250df', label: 'Purple' },
4931
+ ];
4932
+ picker.value = 'green';
4933
+ picker.addEventListener('lyra-change', (e) => console.log(e.detail.value));
4934
+ </script>
4935
+ ```
4936
+
4937
+ **Known gotchas:**
4938
+ - arrow-key navigation cycles (past the last swatch wraps to the first, and vice versa) rather than
4939
+ clamping, and self-selects on move — arrow-navigating to a swatch immediately updates `value` and
4940
+ fires `lyra-change`, there's no separate commit step.
4941
+ - under RTL (nearest `dir="rtl"` ancestor) `ArrowLeft`/`ArrowRight` swap which direction they move.
4942
+ - each swatch's fill comes from its option's `color`, applied through a per-swatch custom property
4943
+ so a consumer's `::part(swatch)` `background-color` rule can still override it.
4944
+ - the semantic `radiogroup` lives inside shadow DOM. Set `label` (preferred for reactive code) or a
4945
+ host `aria-label`; the component deliberately forwards the resulting name to that internal role.
4946
+
4947
+ ---
4948
+
3863
4949
  ## `lyra-checkbox`
3864
4950
 
3865
4951
  A boolean form control. `role="checkbox"` with an `aria-checked` that can also be `"mixed"`, and a
@@ -4020,22 +5106,32 @@ stack overflow on cyclic `data`.
4020
5106
  - `search: string = ''` — case-insensitive substring match against keys/values; matches are
4021
5107
  highlighted and their ancestors auto-expanded
4022
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
+
4023
5115
  **Events:** `lyra-copy` (`detail: { text: string }`) — fired by the top-level copy button or a
4024
5116
  per-node one. Fires even when `navigator.clipboard` is unavailable or the write silently failed
4025
5117
  (a rejected `writeText()` is swallowed), so a consumer can still observe copy *intent* — the event
4026
5118
  is not a confirmation that the OS clipboard was actually reached. Copying a circular `data` value
4027
5119
  serializes safely, substituting the same `Circular reference` marker the tree view renders, instead
4028
- 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.
4029
5123
 
4030
5124
  **Slots:** none — the tree is rendered entirely from `data`.
4031
5125
 
4032
5126
  **CSS parts:** `base` (root scroll container, respects `max-height`), `toolbar` (wrapper around the
4033
5127
  top-level copy button, only rendered when `copyable`), `tree` (wrapper around the rendered node
4034
- 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),
4035
5130
  `value` (a primitive value's text — carries `data-type` of
4036
- `string`/`number`/`boolean`/`null`/`undefined`/`circular` for per-type coloring, and `data-match`
4037
- while it matches `search`), `bracket` (a `{`, `}`, `[`, or `]` delimiter), `toggle` (a container
4038
- 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),
4039
5135
  `copy-button` (a copy-to-clipboard button — the top-level one in `toolbar` (aria-label "Copy JSON to
4040
5136
  clipboard") or a per-node one (aria-label `Copy ${key/type}`, e.g. "Copy age"); only rendered when
4041
5137
  `copyable`)
@@ -4180,6 +5276,15 @@ instance on a page shares one load. `heading`/`code`/`blockquote`/`table`/`link`
4180
5276
  rendered through a `marked` renderer override that injects `part="..."` attributes directly into the
4181
5277
  produced HTML in a single pass (no second DOM walk after insertion).
4182
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
+
4183
5288
  **Properties:**
4184
5289
  - `content: string = ''` — the Markdown source to render
4185
5290
  - `sanitize: boolean = true` — sanitize `marked`'s HTML output with DOMPurify before rendering
@@ -4214,6 +5319,27 @@ produced HTML in a single pass (no second DOM walk after insertion).
4214
5319
  - `streaming: boolean = false` (reflected) — marks the host `aria-busy="true"` while partial Markdown
4215
5320
  is still arriving and lets consumers target `lyra-markdown[streaming]`; busy state also remains
4216
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`.
4217
5343
 
4218
5344
  **Events:** `lyra-link-click` (`detail: { href: string, internal: true }`, fired — with the click
4219
5345
  prevented — when a rendered link's `href` starts with `internal-link-prefix`; ordinary external
@@ -4238,7 +5364,10 @@ Menlo, Consolas, monospace` — the code/code-block font; component-specific sin
4238
5364
  **Optional peer deps:** `marked`, `dompurify` (both lazy-loaded via `markdown-loader.ts`'s
4239
5365
  `loadMarkdownDeps()`, mirroring `chart-loader.ts`'s two-independent-optional-peers shape). Each half
4240
5366
  is loaded and caught independently — a consumer who installs only `marked` and explicitly sets
4241
- `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).
4242
5371
 
4243
5372
  ```html
4244
5373
  <lyra-markdown
@@ -4315,6 +5444,10 @@ conversation-surface level).
4315
5444
  rendered) — mirrors `lyra-widget`'s identical `collapsible`/`collapsed` pair
4316
5445
  - `attachmentsPosition: 'before'|'after' = 'after'` (attribute `attachments-position`) — places the
4317
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
4318
5451
 
4319
5452
  **Events:** `lyra-retry` (no detail payload; fired by the built-in retry button, only rendered when
4320
5453
  `status="failed"`), `lyra-collapse-toggle` (`detail: boolean`, the new `collapsed` state — fired when
@@ -4330,6 +5463,8 @@ attachment chips, rendered below the message body)
4330
5463
  `attachments`, `footer` (hidden entirely when nothing is in it), `status-indicator` (a small
4331
5464
  decorative `aria-hidden` dot, absent while `status="sent"`), `status-text` (the visible text twin of
4332
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)
4333
5468
 
4334
5469
  **Themeable custom properties:** `--lyra-chat-message-max-width` (default `80%` — the bubble's max
4335
5470
  inline size; component-specific, no shared width token exists), plus shared tokens
@@ -5235,6 +6370,15 @@ invention (no Web Awesome equivalent).
5235
6370
  - `rowHeight: string = 'auto'` (attribute `row-height`) — `'auto'` measures each row's real height via
5236
6371
  `ResizeObserver`; a numeric string (e.g. `"56"`) fixes every row to that many pixels. Anything else
5237
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.
5238
6382
  - `overscan: number = 6` — extra rows rendered beyond the visible viewport on each side; finite
5239
6383
  values are floored and clamped to 0–100, while non-finite values use the default 6, so an invalid
5240
6384
  runtime value cannot disable windowing and render the entire collection.
@@ -5254,6 +6398,12 @@ The package root also exports `groupByRecency(items, options?)`, a DOM-free help
5254
6398
  non-empty Today/Yesterday/Previous 7 Days/Older buckets, preserves input order within each bucket,
5255
6399
  and accepts a timestamp extractor, reference date, and label overrides.
5256
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
+
5257
6407
  **Events:** `lyra-load-more` (no detail — fired once per approach to the bottom of the list while
5258
6408
  `has-more` is true and `loading` is false; does not refire on every scroll tick while still near the
5259
6409
  bottom — scrolling back away from the bottom and returning, or `items` growing enough to move the
@@ -5262,10 +6412,12 @@ current visible, non-overscanned item index range — fired only when it actuall
5262
6412
 
5263
6413
  **Slots:** none — all content comes from `renderItem`.
5264
6414
 
5265
- **CSS parts:** `base` (the scrollable container, `role="list"`, `tabindex="0"`), `spacer` (the
5266
- full-content-height inner element establishing true scroll extent), `row` (one rendered row's
5267
- absolutely-positioned wrapper, `role="listitem"`), `group` (a `groups` entry's positioned
5268
- `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)
5269
6421
 
5270
6422
  **Themeable custom properties:** `--lyra-virtual-list-height` (default `24rem` — the host's bounded
5271
6423
  scroll extent; component-specific since a virtualized list is meaningless without a sized viewport),
@@ -6685,6 +7837,19 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6685
7837
  code scrolls internally past this height instead of growing the page
6686
7838
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6687
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.
6688
7853
  - `languages?: Record<string, ShikiLanguageInput>` (attribute: false) — a map of language id to an
6689
7854
  already-imported shiki grammar module (e.g. `{ bash: bashGrammar }` from a module-scope
6690
7855
  `import bash from 'shiki/langs/bash.mjs'`). When `language` matches a key here, highlighting is
@@ -6696,15 +7861,26 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
6696
7861
  - `languagesOnly: boolean = false` (attribute `languages-only`) — skips the default shiki loader;
6697
7862
  use when every requested language is supplied through `languages`
6698
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
+
6699
7868
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6700
7869
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6701
7870
  `lyra-toggle` (`detail: { collapsed: boolean }` — fired when the built-in collapse/expand header
6702
- 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)
6703
7877
 
6704
7878
  **Slots:** none.
6705
7879
 
6706
7880
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6707
- `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)
6708
7884
 
6709
7885
  **Themeable custom properties:** `--lyra-code-block-max-height` (default `none` — the consumer-tunable
6710
7886
  scroll cap; only takes effect once `max-height` is set), `--lyra-code-block-font` (default
@@ -6802,19 +7978,40 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
6802
7978
  code scrolls internally past this height instead of growing the page.
6803
7979
  - `lineNumbers: boolean = false` (attribute `line-numbers`, reflected) — displays one-based line
6804
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>`.
6805
7993
  - `languages: Record<string, ShikiLanguageInput> = {}` (attribute: false) — grammar definitions this
6806
7994
  instance can highlight, e.g. `{ json: jsonGrammar }` (import from `shiki/langs/<name>.mjs`). Empty
6807
7995
  (the default) never highlights at all — every `language` renders the plain-text fallback.
6808
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
+
6809
8002
  **Events:** `lyra-copy` (`detail: { text: string }` — always the raw `code` value, never the
6810
8003
  highlighted HTML, and always fires regardless of whether the actual OS clipboard write succeeded),
6811
8004
  `lyra-toggle` (`detail: { collapsed: boolean }` — fired when the built-in collapse/expand header
6812
- 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).
6813
8010
 
6814
8011
  **Slots:** none.
6815
8012
 
6816
8013
  **CSS parts:** `base`, `header`, `filename`, `language`, `copy-button`, `toggle`, `body`, `pre`,
6817
- `code` — identical set to `<lyra-code-block>`.
8014
+ `code`, `line-highlight`, `line-button` — identical set to `<lyra-code-block>`.
6818
8015
 
6819
8016
  **Themeable custom properties:** identical to `<lyra-code-block>` — `--lyra-code-block-max-height`,
6820
8017
  `--lyra-code-block-font`, plus the same shared tokens.
@@ -6861,6 +8058,15 @@ First-party invention (no Web Awesome equivalent).
6861
8058
  all-removals diff of `oldText`.
6862
8059
  - `copyable: boolean = false` — shows a copy-to-clipboard button for the full unified-diff text.
6863
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`.
6864
8070
 
6865
8071
  **Events:** `lyra-copy` (`detail: { text: string }` — the full unified-diff text, fired on
6866
8072
  copy-button activation regardless of whether the clipboard write actually succeeded).
@@ -6868,15 +8074,19 @@ copy-button activation regardless of whether the clipboard write actually succee
6868
8074
  **Slots:** none.
6869
8075
 
6870
8076
  **CSS parts:** `base` (the root wrapper), `line` (a single line; carries
6871
- `data-type="equal"|"add"|"remove"`), `copy-button` (the copy affordance, only rendered while
6872
- `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"`).
6873
8080
 
6874
8081
  **Themeable custom properties:** `--lyra-diff-view-font` (default `var(--lyra-font-mono)`), plus
6875
8082
  shared tokens `--lyra-color-border`/`-surface`/`-success`/`-success-quiet`/`-danger`/
6876
8083
  `-danger-quiet`/`-text`, `--lyra-radius`, `--lyra-space-xs`/`-s`, `--lyra-font-size-sm`,
6877
8084
  `--lyra-line-height-snug`, `--lyra-focus-ring-*`.
6878
8085
 
6879
- **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.
6880
8090
 
6881
8091
  ```html
6882
8092
  <lyra-diff-view copyable></lyra-diff-view>
@@ -6904,6 +8114,72 @@ consumer can compute or unit-test the same alignment without instantiating the e
6904
8114
 
6905
8115
  ---
6906
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
+
6907
8183
  ## `lyra-tool-approval-dialog`
6908
8184
 
6909
8185
  A human-in-the-loop gate: presents one proposed tool/function call (`toolName` + `args`) and blocks an
@@ -7553,8 +8829,9 @@ used" summary.
7553
8829
 
7554
8830
  **Properties:**
7555
8831
  - `segments: ContextMeterSegment[] = []` (attribute: false, JS-only) — `{ label: string; value:
7556
- 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*
7557
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`.
7558
8835
  - `total: number = 0` — the full capacity segments are measured against (e.g. a model's context
7559
8836
  window size).
7560
8837
  - `variant: 'ring' | 'bar' = 'bar'` (reflected)
@@ -7569,9 +8846,11 @@ A host `aria-label` overrides the generated meter summary and is preserved acros
7569
8846
  **Slots:** none.
7570
8847
 
7571
8848
  **CSS parts:** `base` (a `<div>` for `bar`, an `<svg>` for `ring`), `track` (the unfilled/empty
7572
- 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`
7573
8851
 
7574
- **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
7575
8854
  `--lyra-space-xs`, `--lyra-color-text-quiet`, `--lyra-font`, `--lyra-radius`, `--lyra-color-border`,
7576
8855
  `--lyra-color-surface` (the bar variant's inter-segment seam), `--lyra-color-brand`,
7577
8856
  `--lyra-color-success`, `--lyra-color-warning`, `--lyra-color-danger`, `--lyra-transition-base`.
@@ -7774,6 +9053,20 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7774
9053
  - `maxHeight: string = ''` (attribute `max-height`) — a CSS length (e.g. `"24rem"`); once set,
7775
9054
  `[part="body"]` scrolls internally past this height instead of growing the page — same contract as
7776
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`.
7777
9070
 
7778
9071
  **Events:**
7779
9072
  - `lyra-download` — `detail: { src, filename }` — fired when the generic-download fallback's link is
@@ -7782,6 +9075,8 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
7782
9075
  - `lyra-render-error` — `detail: { error }` — fired when this component's own `text/*`/
7783
9076
  `application/json` `fetch(src)` fails (network error or non-2xx response). Distinct from
7784
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).
7785
9080
 
7786
9081
  **Slots:** `unsupported` — escape hatch: when populated, its content renders *instead of* the generic
7787
9082
  download fallback for any `mime-type` this component doesn't natively support. Ignored while
@@ -7792,7 +9087,11 @@ download fallback for any `mime-type` this component doesn't natively support. I
7792
9087
  used both for `status="converting"` and this component's own in-flight text fetch), `error`
7793
9088
  (`role="alert"` — used both for `status="error"` and a failed text fetch), `download-link` (only
7794
9089
  rendered when `src` is set *and* passes the link-safe scheme allowlist — see the URL-safety note
7795
- 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)
7796
9095
 
7797
9096
  **Themeable custom properties:** `--lyra-document-preview-max-height` (default `none`) — the
7798
9097
  consumer-tunable scroll cap on `[part="body"]`, set from `max-height`; `none` means the preview grows
@@ -7877,6 +9176,13 @@ type. First-party invention.
7877
9176
  - `src: string = ''` — source URL passed to the selected renderer or the fallback preview.
7878
9177
  - `registry?: DocumentRendererRegistry` (attribute: false) — optional per-instance registry override;
7879
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.
7880
9186
 
7881
9187
  **Events:**
7882
9188
  - `lyra-close` — `detail: DocumentViewerCloseReason`, the nested dialog's dismissal reason. The
@@ -7928,13 +9234,33 @@ Mammoth preserves document structure such as headings, paragraphs, lists, tables
7928
9234
  not intended to reproduce pixel-exact Word page layout. There is no unsanitized rendering escape
7929
9235
  hatch: if `dompurify` is unavailable, rendering is blocked even when Mammoth converted successfully.
7930
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
+
7931
9242
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
7932
- 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.
7933
9252
 
7934
9253
  **Events:** `lyra-render-error` with `detail.error` when fetching, conversion, sanitization, or a
7935
- 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.
7936
9260
 
7937
- **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`).
7938
9264
 
7939
9265
  **Optional peer dependencies:** install `mammoth` and `dompurify` with `pnpm add mammoth dompurify`.
7940
9266
  The component registers an eager `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
@@ -7959,13 +9285,17 @@ remain available without DOMPurify. Attachments are listed as filename and size
7959
9285
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
7960
9286
  `documentPreviewResourceTooLarge` message instead of the message.
7961
9287
 
7962
- **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.
7963
9291
 
7964
9292
  **Events:** `lyra-render-error` with `detail.error` when fetching or parsing fails.
7965
9293
 
7966
9294
  **CSS parts:** `base`, `headers`, `from-label`, `from`, `to-label`, `to`, `subject-label`, `subject`,
7967
9295
  `date-label`, `date`, `body`, `body-html`, `body-text`, `attachments`, `attachments-label`,
7968
- `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`.
7969
9299
 
7970
9300
  **Optional peer dependencies:** install `postal-mime` and `dompurify` with
7971
9301
  `pnpm add postal-mime dompurify`. The component registers `message/rfc822` and falls back to
@@ -8021,19 +9351,48 @@ epub.js renders the reading area into its stable `mount` element, using an inter
8021
9351
  chapter content.
8022
9352
 
8023
9353
  **Properties:** `src` and `name` are strings. `accessibleLabel` (attribute `aria-label`) overrides
8024
- the reading region's accessible name.
8025
-
8026
- **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()`.
8027
9375
 
8028
9376
  **CSS parts:** `base`, `toolbar`, `previous-button`, `next-button`, `previous-icon`, `next-icon`,
8029
- `mount`, and `error`.
9377
+ `mount`, `error`, and `announcer` (the visually-hidden `role="status"` region search results
9378
+ announce through).
8030
9379
 
8031
9380
  **Optional peer dependency:** install `epubjs` with `pnpm add epubjs`. The document-viewer registry
8032
- 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.
8033
9383
 
8034
9384
  Remote resources are capped at 25 MB; exceeding it surfaces the localized
8035
9385
  `documentPreviewResourceTooLarge` message instead of the ebook.
8036
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
+
8037
9396
  ## `lyra-pptx-viewer`
8038
9397
 
8039
9398
  Best-effort client-side PPTX viewer backed by the optional `@aiden0z/pptx-renderer` peer. A
@@ -8066,10 +9425,10 @@ spreadsheet, presentation, code, archive, image, audio, and video formats. An ex
8066
9425
  type wins; filename extension fallback is used only for an empty or `application/octet-stream`
8067
9426
  MIME type. Unknown values return a generic file result.
8068
9427
 
8069
- **Properties:** `mimeType` (attribute `mime-type`), `name`, `label`, `decorative`, and
8070
- `variant: 'icon' | 'label'`.
9428
+ **Properties:** `mimeType` (attribute `mime-type`), `name`, `size` (bytes; `0` renders no size),
9429
+ `label`, `decorative`, and `variant: 'icon' | 'label'`.
8071
9430
 
8072
- **CSS parts:** `base`, `icon`, and `label`.
9431
+ **CSS parts:** `base`, `icon`, `label`, and `size`.
8073
9432
 
8074
9433
  **Exports:** `LyraFileTypeMetadata`, `LyraFileTypeIcon`, `LyraFileTypeCategory`,
8075
9434
  `getFileTypeMetadata()`, and `registerFileTypeMetadata()` for application-specific mappings.
@@ -8083,11 +9442,28 @@ MIME type. Unknown values return a generic file result.
8083
9442
  Fetches an SVG document, sanitizes it with the optional `dompurify` peer, and renders it inline.
8084
9443
 
8085
9444
  **Properties:** `src`, `name`, and `maxHeight` (attribute `max-height`) are strings. `maxHeight` caps
8086
- 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`).
8087
9458
 
8088
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.
8089
9462
 
8090
- **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`).
8091
9467
 
8092
9468
  **Optional peer dependency:** `dompurify`.
8093
9469
 
@@ -8112,23 +9488,44 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8112
9488
 
8113
9489
  ## `lyra-dataset-viewer`
8114
9490
 
8115
- Fetches tab-, pipe-, or delimiter-separated text and renders an accessible table using the optional
8116
- `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.
8117
9495
 
8118
- **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.
8119
9510
 
8120
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()`.
8121
9516
 
8122
- **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`.
8123
9521
 
8124
9522
  **Exports:** `DatasetTable` is `{ fields: string[]; rows: Record<string, string>[] }`.
8125
9523
 
8126
9524
  **Optional peer dependency:** `papaparse`.
8127
9525
 
8128
- Remote resources are capped at 25 MB, and the parsed table at 1,000 rows and 1,000 columns (lower
8129
- than `lyra-csv-viewer`/`lyra-spreadsheet-viewer`'s shared 10,000-row cap, since this component renders
8130
- every row into a real, non-virtualized `<table>` in one synchronous pass); exceeding any of these
8131
- 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.
8132
9529
 
8133
9530
  ## `lyra-contact-viewer`
8134
9531
 
@@ -8156,13 +9553,23 @@ Fetches a PDF and renders its pages with the optional `pdfjs-dist` peer. Pages a
8156
9553
  `lyra-virtual-list`, and PDF.js's selectable text layer is positioned over each rendered canvas.
8157
9554
 
8158
9555
  **Properties:** `src` and `name` are strings. `page: number = 1` is the one-based current page and
8159
- `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).
8160
9558
 
8161
9559
  **Events:** `lyra-render-error` with `detail.error` when fetching, parsing, or rendering fails;
8162
9560
  `lyra-page-change` with `{ page, pageCount }`; and `lyra-zoom-change` with `{ zoom }`.
8163
9561
 
8164
9562
  **Methods:** `nextPage()`, `previousPage()`, `zoomIn()`, and `zoomOut()` update the corresponding
8165
- 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.
8166
9573
 
8167
9574
  **CSS parts:** `base`, `toolbar`, `page-indicator`, `zoom-indicator`, `pages`, `page`, `text-layer`,
8168
9575
  `spinner`, and `error`.
@@ -8179,14 +9586,31 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
8179
9586
  Fetches and renders `.xlsx` and `.xls` workbooks with the optional `xlsx` (SheetJS) peer. Multiple
8180
9587
  worksheets render through a `<lyra-tabs>` switcher, and body rows use `<lyra-virtual-list>`.
8181
9588
 
8182
- **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.
8183
9603
 
8184
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()`.
8185
9609
 
8186
- **CSS parts:** `base`, `tabs`, `sheet`, `header-row`, `data-row`, `cell`, `rows`, `spinner`, and
8187
- `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`.
8188
9612
 
8189
- **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
8190
9614
  `.xlsx` and `.xls` MIME types and filename extensions.
8191
9615
 
8192
9616
  Remote resources are capped at 25 MB, and each parsed sheet at 10,000 rows and 1,000 columns;
@@ -8197,12 +9621,30 @@ the workbook.
8197
9621
 
8198
9622
  Fetches CSV text, parses quoted fields with the optional `papaparse` peer, and virtualizes body rows.
8199
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
+
8200
9629
  **Properties:** `src` and `name` are strings. `hasHeaderRow: boolean = true` (attribute
8201
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.
8202
9639
 
8203
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()`.
8204
9645
 
8205
- **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`.
8206
9648
 
8207
9649
  **Optional peer dependency:** install `papaparse` with `pnpm add papaparse`. The registry matches
8208
9650
  `text/csv` and `.csv` filenames.
@@ -8880,6 +10322,41 @@ Groups avatars and collapses excess members into a localized overflow indicator.
8880
10322
  `max`, `shape`, `size`, and `tone`. The default slot accepts avatar elements. **CSS parts:** `base`,
8881
10323
  `avatars`, and `overflow`.
8882
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
+
8883
10360
  ## `lyra-include`
8884
10361
 
8885
10362
  Loads HTML or text from `src` into the component. **Properties:** `src` and `mode` (`html` or `text`).
@@ -8988,3 +10465,1130 @@ These apply across the whole library rather than to any one component:
8988
10465
  - **RTL.** Components generally rely on CSS logical properties to flip layout for free; `lyra-split`
8989
10466
  and `lyra-time-range` additionally consult `internal/rtl.ts`'s `isRtl()` to mirror the physical
8990
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.