@aceshooting/lyra-ui 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/README.md +12 -1
  2. package/custom-elements.json +21460 -8489
  3. package/dist/components/app-rail/app-rail.d.ts +171 -0
  4. package/dist/components/app-rail/app-rail.js +483 -0
  5. package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail.styles.js +125 -0
  7. package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
  8. package/dist/components/attachment-chip/attachment-chip.js +312 -0
  9. package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
  10. package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
  11. package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
  12. package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
  13. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
  14. package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
  15. package/dist/components/chart/box-plot.js +11 -1
  16. package/dist/components/chart/chart-loader.d.ts +44 -13
  17. package/dist/components/chart/chart-loader.js +65 -18
  18. package/dist/components/chart/chart.d.ts +12 -2
  19. package/dist/components/chart/chart.js +121 -14
  20. package/dist/components/chart/histogram-bin.d.ts +4 -1
  21. package/dist/components/chart/histogram-bin.js +24 -14
  22. package/dist/components/chart/lite-chart.d.ts +63 -0
  23. package/dist/components/chart/lite-chart.js +181 -23
  24. package/dist/components/chart/lite-chart.styles.js +9 -0
  25. package/dist/components/chat-composer/chat-composer.d.ts +92 -0
  26. package/dist/components/chat-composer/chat-composer.js +285 -0
  27. package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
  28. package/dist/components/chat-composer/chat-composer.styles.js +135 -0
  29. package/dist/components/chat-message/chat-message.d.ts +113 -0
  30. package/dist/components/chat-message/chat-message.js +291 -0
  31. package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
  32. package/dist/components/chat-message/chat-message.styles.js +203 -0
  33. package/dist/components/checkbox/checkbox.d.ts +59 -0
  34. package/dist/components/checkbox/checkbox.js +230 -0
  35. package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
  36. package/dist/components/checkbox/checkbox.styles.js +70 -0
  37. package/dist/components/chip/chip-group.d.ts +56 -0
  38. package/dist/components/chip/chip-group.js +124 -0
  39. package/dist/components/chip/chip-group.styles.d.ts +1 -0
  40. package/dist/components/chip/chip-group.styles.js +57 -0
  41. package/dist/components/chip/chip.d.ts +64 -0
  42. package/dist/components/chip/chip.js +115 -0
  43. package/dist/components/chip/chip.styles.d.ts +1 -0
  44. package/dist/components/chip/chip.styles.js +115 -0
  45. package/dist/components/citation-badge/citation-badge.d.ts +113 -0
  46. package/dist/components/citation-badge/citation-badge.js +300 -0
  47. package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
  48. package/dist/components/citation-badge/citation-badge.styles.js +96 -0
  49. package/dist/components/code-block/code-block.d.ts +89 -0
  50. package/dist/components/code-block/code-block.js +317 -0
  51. package/dist/components/code-block/code-block.styles.d.ts +1 -0
  52. package/dist/components/code-block/code-block.styles.js +187 -0
  53. package/dist/components/code-block/code-loader.d.ts +44 -0
  54. package/dist/components/code-block/code-loader.js +79 -0
  55. package/dist/components/combobox/combobox.d.ts +19 -1
  56. package/dist/components/combobox/combobox.js +84 -14
  57. package/dist/components/combobox/option.d.ts +5 -1
  58. package/dist/components/combobox/option.js +35 -0
  59. package/dist/components/context-meter/context-meter.d.ts +53 -0
  60. package/dist/components/context-meter/context-meter.js +150 -0
  61. package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
  62. package/dist/components/context-meter/context-meter.styles.js +120 -0
  63. package/dist/components/conversation-item/conversation-item.d.ts +128 -0
  64. package/dist/components/conversation-item/conversation-item.js +322 -0
  65. package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
  66. package/dist/components/conversation-item/conversation-item.styles.js +155 -0
  67. package/dist/components/date-picker/date-input.d.ts +24 -0
  68. package/dist/components/date-picker/date-input.js +134 -22
  69. package/dist/components/date-picker/date-picker.d.ts +7 -0
  70. package/dist/components/date-picker/date-picker.js +85 -16
  71. package/dist/components/dialog/confirm.d.ts +40 -0
  72. package/dist/components/dialog/confirm.js +79 -0
  73. package/dist/components/dialog/dialog.d.ts +85 -0
  74. package/dist/components/dialog/dialog.js +272 -0
  75. package/dist/components/dialog/dialog.styles.d.ts +1 -0
  76. package/dist/components/dialog/dialog.styles.js +52 -0
  77. package/dist/components/dock-panel/dock-panel.d.ts +134 -0
  78. package/dist/components/dock-panel/dock-panel.js +345 -0
  79. package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
  80. package/dist/components/dock-panel/dock-panel.styles.js +145 -0
  81. package/dist/components/document-preview/document-preview.d.ts +135 -0
  82. package/dist/components/document-preview/document-preview.js +372 -0
  83. package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
  84. package/dist/components/document-preview/document-preview.styles.js +191 -0
  85. package/dist/components/export-button/csv.js +1 -1
  86. package/dist/components/export-button/export-button.js +2 -0
  87. package/dist/components/flag/flag.d.ts +42 -5
  88. package/dist/components/flag/flag.js +70 -3
  89. package/dist/components/gauge/gauge.js +19 -10
  90. package/dist/components/generation-status/generation-status.d.ts +109 -0
  91. package/dist/components/generation-status/generation-status.js +273 -0
  92. package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
  93. package/dist/components/generation-status/generation-status.styles.js +84 -0
  94. package/dist/components/heatmap/calendar-grid.d.ts +4 -1
  95. package/dist/components/heatmap/calendar-grid.js +25 -12
  96. package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
  97. package/dist/components/heatmap/heatmap-scale.js +7 -1
  98. package/dist/components/heatmap/heatmap.d.ts +89 -3
  99. package/dist/components/heatmap/heatmap.js +158 -29
  100. package/dist/components/json-viewer/json-viewer.d.ts +53 -0
  101. package/dist/components/json-viewer/json-viewer.js +283 -0
  102. package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
  103. package/dist/components/json-viewer/json-viewer.styles.js +176 -0
  104. package/dist/components/kbd/kbd.d.ts +77 -0
  105. package/dist/components/kbd/kbd.js +214 -0
  106. package/dist/components/kbd/kbd.styles.d.ts +1 -0
  107. package/dist/components/kbd/kbd.styles.js +52 -0
  108. package/dist/components/live-region/live-region.d.ts +81 -0
  109. package/dist/components/live-region/live-region.js +153 -0
  110. package/dist/components/live-region/live-region.styles.d.ts +1 -0
  111. package/dist/components/live-region/live-region.styles.js +10 -0
  112. package/dist/components/map/map.d.ts +8 -6
  113. package/dist/components/map/map.js +44 -8
  114. package/dist/components/markdown/markdown-loader.d.ts +34 -0
  115. package/dist/components/markdown/markdown-loader.js +43 -0
  116. package/dist/components/markdown/markdown.d.ts +81 -0
  117. package/dist/components/markdown/markdown.js +284 -0
  118. package/dist/components/markdown/markdown.styles.d.ts +1 -0
  119. package/dist/components/markdown/markdown.styles.js +82 -0
  120. package/dist/components/media-card/media-card.d.ts +122 -0
  121. package/dist/components/media-card/media-card.js +295 -0
  122. package/dist/components/media-card/media-card.styles.d.ts +1 -0
  123. package/dist/components/media-card/media-card.styles.js +132 -0
  124. package/dist/components/mention-popover/mention-popover.d.ts +200 -0
  125. package/dist/components/mention-popover/mention-popover.js +475 -0
  126. package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
  127. package/dist/components/mention-popover/mention-popover.styles.js +101 -0
  128. package/dist/components/menu/menu-item.d.ts +62 -0
  129. package/dist/components/menu/menu-item.js +119 -0
  130. package/dist/components/menu/menu-item.styles.d.ts +1 -0
  131. package/dist/components/menu/menu-item.styles.js +67 -0
  132. package/dist/components/menu/menu.d.ts +143 -0
  133. package/dist/components/menu/menu.js +365 -0
  134. package/dist/components/menu/menu.styles.d.ts +1 -0
  135. package/dist/components/menu/menu.styles.js +66 -0
  136. package/dist/components/model-select/model-select.d.ts +125 -0
  137. package/dist/components/model-select/model-select.js +490 -0
  138. package/dist/components/model-select/model-select.styles.d.ts +1 -0
  139. package/dist/components/model-select/model-select.styles.js +189 -0
  140. package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
  141. package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
  142. package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
  143. package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
  144. package/dist/components/playback/playback.d.ts +13 -1
  145. package/dist/components/playback/playback.js +47 -14
  146. package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
  147. package/dist/components/responsive-panel/responsive-panel.js +365 -0
  148. package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
  149. package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
  150. package/dist/components/result-card/result-card.d.ts +44 -0
  151. package/dist/components/result-card/result-card.js +83 -0
  152. package/dist/components/result-card/result-card.styles.d.ts +1 -0
  153. package/dist/components/result-card/result-card.styles.js +50 -0
  154. package/dist/components/result-card/result-field.d.ts +36 -0
  155. package/dist/components/result-card/result-field.js +87 -0
  156. package/dist/components/result-card/result-field.styles.d.ts +1 -0
  157. package/dist/components/result-card/result-field.styles.js +32 -0
  158. package/dist/components/select/select.d.ts +45 -1
  159. package/dist/components/select/select.js +114 -17
  160. package/dist/components/select/select.styles.js +26 -2
  161. package/dist/components/slider/slider.d.ts +89 -0
  162. package/dist/components/slider/slider.js +352 -0
  163. package/dist/components/slider/slider.styles.d.ts +1 -0
  164. package/dist/components/slider/slider.styles.js +87 -0
  165. package/dist/components/source-card/source-card.d.ts +92 -0
  166. package/dist/components/source-card/source-card.js +148 -0
  167. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  168. package/dist/components/source-card/source-card.styles.js +69 -0
  169. package/dist/components/source-list/source-list.d.ts +63 -0
  170. package/dist/components/source-list/source-list.js +122 -0
  171. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  172. package/dist/components/source-list/source-list.styles.js +59 -0
  173. package/dist/components/sparkline/sparkline.js +27 -13
  174. package/dist/components/split/split.d.ts +93 -1
  175. package/dist/components/split/split.js +284 -15
  176. package/dist/components/split/split.styles.js +30 -0
  177. package/dist/components/stat/stat.d.ts +22 -1
  178. package/dist/components/stat/stat.js +49 -3
  179. package/dist/components/stat/stat.styles.js +20 -0
  180. package/dist/components/stream-status/stream-status.d.ts +110 -0
  181. package/dist/components/stream-status/stream-status.js +210 -0
  182. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  183. package/dist/components/stream-status/stream-status.styles.js +103 -0
  184. package/dist/components/streaming-text/streaming-text.d.ts +98 -0
  185. package/dist/components/streaming-text/streaming-text.js +209 -0
  186. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  187. package/dist/components/streaming-text/streaming-text.styles.js +62 -0
  188. package/dist/components/switch/switch.d.ts +58 -0
  189. package/dist/components/switch/switch.js +179 -0
  190. package/dist/components/switch/switch.styles.d.ts +1 -0
  191. package/dist/components/switch/switch.styles.js +75 -0
  192. package/dist/components/table/table.d.ts +73 -4
  193. package/dist/components/table/table.js +169 -20
  194. package/dist/components/table/table.styles.js +6 -1
  195. package/dist/components/tabs/tabs.d.ts +51 -0
  196. package/dist/components/tabs/tabs.js +190 -0
  197. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  198. package/dist/components/tabs/tabs.styles.js +63 -0
  199. package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
  200. package/dist/components/thinking-panel/thinking-panel.js +235 -0
  201. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  202. package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
  203. package/dist/components/toast/toast-item.d.ts +1 -0
  204. package/dist/components/toast/toast-item.js +31 -6
  205. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
  206. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
  207. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  208. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  209. package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
  210. package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
  211. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  212. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  213. package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
  214. package/dist/components/tool-param-form/tool-param-form.js +366 -0
  215. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  216. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  217. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
  218. package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
  219. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  220. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  221. package/dist/components/tool-result-view/registry.d.ts +81 -0
  222. package/dist/components/tool-result-view/registry.js +84 -0
  223. package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
  224. package/dist/components/tool-result-view/tool-result-view.js +138 -0
  225. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  226. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  227. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  228. package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
  229. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  230. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
  231. package/dist/components/tree/tree-node.d.ts +11 -2
  232. package/dist/components/tree/tree-node.js +16 -6
  233. package/dist/components/tree/tree.d.ts +8 -2
  234. package/dist/components/tree/tree.js +18 -11
  235. package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
  236. package/dist/components/typing-indicator/typing-indicator.js +96 -0
  237. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  238. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  239. package/dist/components/virtual-list/virtual-list.d.ts +173 -0
  240. package/dist/components/virtual-list/virtual-list.js +461 -0
  241. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  242. package/dist/components/virtual-list/virtual-list.styles.js +44 -0
  243. package/dist/components/widget/widget.d.ts +10 -0
  244. package/dist/components/widget/widget.js +24 -1
  245. package/dist/components/widget/widget.styles.js +9 -2
  246. package/dist/components/word-cloud/word-cloud-layout.js +14 -1
  247. package/dist/components/word-cloud/word-cloud.d.ts +6 -0
  248. package/dist/components/word-cloud/word-cloud.js +25 -14
  249. package/dist/components/word-cloud/word-cloud.styles.js +4 -2
  250. package/dist/internal/announcer.d.ts +57 -0
  251. package/dist/internal/announcer.js +71 -0
  252. package/dist/internal/form-associated.d.ts +1 -0
  253. package/dist/internal/form-associated.js +55 -11
  254. package/dist/internal/group-by-recency.d.ts +50 -0
  255. package/dist/internal/group-by-recency.js +80 -0
  256. package/dist/internal/rtl.d.ts +23 -0
  257. package/dist/internal/rtl.js +28 -0
  258. package/dist/internal/scroll-lock.d.ts +10 -5
  259. package/dist/internal/scroll-lock.js +30 -14
  260. package/dist/internal/tokens.styles.js +6 -0
  261. package/dist/lyra.d.ts +130 -31
  262. package/dist/lyra.js +94 -26
  263. package/llms-full.txt +3921 -32
  264. package/llms.txt +16 -1
  265. package/package.json +23 -5
  266. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  267. package/dist/components/chart/bar-chart.stories.js +0 -20
  268. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  269. package/dist/components/chart/box-plot.stories.js +0 -29
  270. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  271. package/dist/components/chart/bubble-chart.stories.js +0 -26
  272. package/dist/components/chart/chart.stories.d.ts +0 -32
  273. package/dist/components/chart/chart.stories.js +0 -141
  274. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  275. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  276. package/dist/components/chart/histogram.stories.d.ts +0 -5
  277. package/dist/components/chart/histogram.stories.js +0 -17
  278. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  279. package/dist/components/chart/line-chart.stories.js +0 -99
  280. package/dist/components/chart/lite-chart.stories.d.ts +0 -12
  281. package/dist/components/chart/lite-chart.stories.js +0 -98
  282. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  283. package/dist/components/chart/pie-chart.stories.js +0 -26
  284. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  285. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  286. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  287. package/dist/components/chart/radar-chart.stories.js +0 -20
  288. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  289. package/dist/components/chart/scatter-chart.stories.js +0 -31
  290. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  291. package/dist/components/combobox/combobox.stories.js +0 -102
  292. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  293. package/dist/components/date-picker/date-input.stories.js +0 -48
  294. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  295. package/dist/components/date-picker/date-picker.stories.js +0 -25
  296. package/dist/components/empty/empty.stories.d.ts +0 -7
  297. package/dist/components/empty/empty.stories.js +0 -34
  298. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  299. package/dist/components/export-button/export-button.stories.js +0 -37
  300. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  301. package/dist/components/file-input/file-input.stories.js +0 -19
  302. package/dist/components/flag/flag.stories.d.ts +0 -5
  303. package/dist/components/flag/flag.stories.js +0 -17
  304. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  305. package/dist/components/gauge/gauge.stories.js +0 -19
  306. package/dist/components/graph/graph.stories.d.ts +0 -8
  307. package/dist/components/graph/graph.stories.js +0 -68
  308. package/dist/components/heatmap/heatmap.stories.d.ts +0 -22
  309. package/dist/components/heatmap/heatmap.stories.js +0 -154
  310. package/dist/components/map/map.stories.d.ts +0 -15
  311. package/dist/components/map/map.stories.js +0 -135
  312. package/dist/components/playback/playback.stories.d.ts +0 -7
  313. package/dist/components/playback/playback.stories.js +0 -16
  314. package/dist/components/select/select.stories.d.ts +0 -19
  315. package/dist/components/select/select.stories.js +0 -75
  316. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  317. package/dist/components/skeleton/skeleton.stories.js +0 -16
  318. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  319. package/dist/components/sparkline/sparkline.stories.js +0 -39
  320. package/dist/components/split/split.stories.d.ts +0 -7
  321. package/dist/components/split/split.stories.js +0 -36
  322. package/dist/components/stat/stat.stories.d.ts +0 -8
  323. package/dist/components/stat/stat.stories.js +0 -64
  324. package/dist/components/table/table.stories.d.ts +0 -12
  325. package/dist/components/table/table.stories.js +0 -67
  326. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  327. package/dist/components/time-range/time-range.stories.js +0 -26
  328. package/dist/components/toast/toast.stories.d.ts +0 -8
  329. package/dist/components/toast/toast.stories.js +0 -72
  330. package/dist/components/tree/tree.stories.d.ts +0 -9
  331. package/dist/components/tree/tree.stories.js +0 -52
  332. package/dist/components/widget/widget.stories.d.ts +0 -7
  333. package/dist/components/widget/widget.stories.js +0 -41
  334. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  335. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -0,0 +1,461 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, nothing } from 'lit';
8
+ import { property, state } from 'lit/decorators.js';
9
+ import { repeat } from 'lit/directives/repeat.js';
10
+ import { styleMap } from 'lit/directives/style-map.js';
11
+ import { LyraElement } from '../../internal/lyra-element.js';
12
+ import { defineElement } from '../../internal/prefix.js';
13
+ import { styles } from './virtual-list.styles.js';
14
+ /** Fallback per-row height (px) used for any row that hasn't been measured
15
+ * yet in `row-height="auto"` mode -- close enough to a typical single-line
16
+ * chat-list row that the initial scrollbar/spacer size doesn't jump wildly
17
+ * once real measurements arrive. Irrelevant in fixed-`row-height` mode. */
18
+ const DEFAULT_ROW_ESTIMATE_PX = 48;
19
+ function prefersReducedMotion() {
20
+ return typeof window !== 'undefined' && !!window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
21
+ }
22
+ /**
23
+ * `<lyra-virtual-list>` — a generic windowed/virtualized list host. Renders
24
+ * only the items within the current viewport (plus `overscan` padding rows
25
+ * on each side) as real DOM, regardless of how large `items` is, so a
26
+ * multi-thousand-row chat history sidebar (or, in a later phase, a long
27
+ * message thread) stays cheap to scroll.
28
+ *
29
+ * Content is entirely caller-supplied: `renderItem(item, index)` returns
30
+ * whatever `lit-html` value should represent that row (typically a
31
+ * `TemplateResult`), and `keyFunction(item, index)` gives it a stable
32
+ * identity for `repeat()`'s DOM-reconciliation key, so scroll position and
33
+ * any per-row state (e.g. an `<audio>` element's playback position) survive
34
+ * an `items` mutation instead of every row remounting from scratch.
35
+ *
36
+ * **Windowing math.** Every row — in both `row-height` modes — is positioned
37
+ * by a `transform: translateY(offset)` computed from a single cumulative
38
+ * `offsets` array (`offsets[i]` = the pixel top of row `i`), rather than by
39
+ * page flow. This is what lets only a small DOM window exist while the
40
+ * scrollbar still reflects the *true* total content height:
41
+ * - **`row-height="auto"` (default).** Each currently-rendered row is
42
+ * watched by a `ResizeObserver`; its real height lands in a per-key
43
+ * `Map`, and any row not yet measured contributes `DEFAULT_ROW_ESTIMATE_PX`
44
+ * to the offsets array until it has been. `offsets` is *not* the same
45
+ * thing as a page-count-based `padding-top`/`padding-bottom` spacer pair —
46
+ * that approach reflows every unmeasured row's position on every new
47
+ * measurement, which is exactly what per-row transform offsets avoid: only
48
+ * the rows *after* a newly-measured one shift, and even that shift is a
49
+ * cheap style recompute, not a layout-affecting padding change.
50
+ * - **Fixed numeric `row-height`.** No measurement needed — `offsets[i]` is
51
+ * just `i * rowHeightPx`, computed by the exact same cumulative-array code
52
+ * path (a dedicated "single spacer + start-index" special case was
53
+ * considered and would work too, but reusing one code path for both modes
54
+ * avoids maintaining two parallel rendering strategies for a difference
55
+ * that's otherwise just "how is row *i*'s height looked up").
56
+ *
57
+ * The `offsets` array is rebuilt on every update. For the list sizes this
58
+ * component is meant for (a scrollable history sidebar, realistically
59
+ * hundreds to a few thousand rows) that's a trivial `O(n)` arithmetic loop,
60
+ * even at scroll-driven ~60fps; it is *not* the right approach for a
61
+ * hundred-thousand-row list without further work (e.g. a Fenwick/segment
62
+ * tree for `O(log n)` offset queries+updates), which is out of scope here.
63
+ *
64
+ * **Accessibility.** The scroll container is `role="list"` and each rendered
65
+ * row is `role="listitem"`, deliberately *not* `listbox`/`option` — this
66
+ * component only provides windowing, not the roving-tabindex/
67
+ * `aria-activedescendant` keyboard-interaction contract ARIA requires
68
+ * alongside a real `listbox`. A consumer that wants full single-select
69
+ * listbox semantics on top of this should compose that behavior itself (see
70
+ * `<lyra-select>`'s pattern), the same way this component's `active-id`
71
+ * only *scrolls* the matching row into view and marks it `aria-current` —
72
+ * it never claims to be a selection widget. `aria-setsize`/`aria-posinset`
73
+ * are computed from the row's real index in the full `items` array (not its
74
+ * position among the currently-rendered DOM window), so a screen reader
75
+ * still announces e.g. "item 12 of 340" correctly. `[part="base"]` itself
76
+ * carries `tabindex="0"` — `renderItem`'s content is caller-supplied and not
77
+ * guaranteed to contain a focusable element, and a scrollable region with no
78
+ * focusable content of its own is otherwise unreachable by keyboard (native
79
+ * arrow/Page Up/Page Down scrolling included).
80
+ *
81
+ * **Grouping.** `groups` is accepted for forward API compatibility with a
82
+ * later phase's sticky-header sectioning feature (paired with a
83
+ * `groupByRecency()` helper that doesn't exist yet) but is not read or
84
+ * rendered by this pass — every row still renders flat, in `items` order.
85
+ *
86
+ * @customElement lyra-virtual-list
87
+ * @event lyra-load-more - Fired once per approach to the bottom of the list
88
+ * while `has-more` is true and `loading` is false. Deliberately does not
89
+ * refire on every scroll tick while still near the bottom (`loading`
90
+ * gates the in-flight case; scrolling back away from the bottom and
91
+ * returning, or `items` growing enough to move the window away from the
92
+ * end, re-arms it) — a consumer wanting an automatic retry after a failed
93
+ * fetch should surface its own retry affordance rather than relying on
94
+ * this firing again unprompted.
95
+ * @event lyra-visible-range-changed - `detail: { start, end }` (see
96
+ * `VirtualListRange`) — the current visible (non-overscanned) item index
97
+ * range, fired only when it actually changes.
98
+ * @csspart base - The scrollable container (`role="list"`).
99
+ * @csspart spacer - The full-content-height inner element that gives the
100
+ * container its true scrollable extent.
101
+ * @csspart row - One rendered row's absolutely-positioned wrapper
102
+ * (`role="listitem"`); `renderItem`'s return value renders inside it.
103
+ */
104
+ export class LyraVirtualList extends LyraElement {
105
+ constructor() {
106
+ super(...arguments);
107
+ /** The full (non-windowed) item collection. */
108
+ this.items = [];
109
+ /** Renders one row's content — typically returns a `lit-html` `TemplateResult`. */
110
+ this.renderItem = () => nothing;
111
+ /** `'auto'` (default) measures each row's real height via `ResizeObserver`;
112
+ * a numeric string fixes every row to that many pixels. */
113
+ this.rowHeight = 'auto';
114
+ /** Extra rows rendered beyond the visible viewport on each side, to reduce blank-frame risk during fast scrolling. */
115
+ this.overscan = 6;
116
+ /** When set and it matches a row's `keyFunction` result, that row is smoothly scrolled into view whenever this changes. */
117
+ this.activeId = '';
118
+ this.loading = false;
119
+ /** When true, scrolling near the bottom fires `lyra-load-more`. */
120
+ this.hasMore = false;
121
+ // Named distinctly from the inherited DOM `scrollTop` (a `HTMLElement`
122
+ // property this class would otherwise shadow) -- this tracks the *scroll
123
+ // container's* scrollTop, not the host element's own (the host never
124
+ // scrolls itself; [part="base"] does).
125
+ this.containerScrollTop = 0;
126
+ this.viewportHeight = 0;
127
+ /** `offsets[i]` = row `i`'s pixel top; `offsets[items.length]` = total content height. Rebuilt every update. */
128
+ this.offsets = [0];
129
+ /** Parsed `rowHeight`: a positive pixel number, or `null` for `'auto'` (measured) mode. */
130
+ this.fixedRowHeight = null;
131
+ /** `row-height="auto"` per-row measured heights, keyed by `String(keyFunction(item, index))`. */
132
+ this.measuredHeights = new Map();
133
+ this.renderStart = 0;
134
+ this.renderEnd = -1;
135
+ this.visibleStart = 0;
136
+ this.visibleEnd = -1;
137
+ this.lastEmittedStart = -1;
138
+ this.lastEmittedEnd = -1;
139
+ /** Re-armed whenever the window moves away from the end of `items` -- see the `lyra-load-more` event doc. */
140
+ this.loadMoreArmed = true;
141
+ this.isFirstUpdate = true;
142
+ this.observedRows = new Map();
143
+ this.pendingScrollTop = null;
144
+ this.onScroll = (e) => {
145
+ this.pendingScrollTop = e.currentTarget.scrollTop;
146
+ if (this.scrollRafId !== undefined)
147
+ return;
148
+ // Coalesce to one recompute per animation frame -- native `scroll`
149
+ // events can fire far faster than that under a fast trackpad/touch
150
+ // fling, and each recompute is a full Lit update.
151
+ this.scrollRafId = requestAnimationFrame(() => {
152
+ this.scrollRafId = undefined;
153
+ if (this.pendingScrollTop !== null) {
154
+ this.containerScrollTop = this.pendingScrollTop;
155
+ this.pendingScrollTop = null;
156
+ }
157
+ });
158
+ };
159
+ this.onRowsResized = (entries) => {
160
+ if (this.fixedRowHeight != null)
161
+ return;
162
+ let changed = false;
163
+ for (const entry of entries) {
164
+ const key = entry.target.dataset.rowKey;
165
+ if (key === undefined)
166
+ continue;
167
+ const height = entry.borderBoxSize?.[0]?.blockSize ?? entry.target.getBoundingClientRect().height;
168
+ const prev = this.measuredHeights.get(key);
169
+ // A sub-pixel-only difference (common with fractional layout/zoom)
170
+ // isn't worth a full offsets rebuild + re-render.
171
+ if (prev === undefined || Math.abs(prev - height) > 0.5) {
172
+ this.measuredHeights.set(key, height);
173
+ changed = true;
174
+ }
175
+ }
176
+ if (changed)
177
+ this.requestUpdate();
178
+ };
179
+ }
180
+ static { this.styles = [LyraElement.styles, styles]; }
181
+ connectedCallback() {
182
+ super.connectedCallback();
183
+ this.rowResizeObserver = new ResizeObserver(this.onRowsResized);
184
+ // firstUpdated() only ever fires once per element instance -- a
185
+ // disconnect/reconnect (e.g. a reparenting drag) needs its own
186
+ // re-attach here, since the container observer/scroll listener were
187
+ // torn down in disconnectedCallback below.
188
+ if (this.hasUpdated)
189
+ this.attachContainerListeners();
190
+ }
191
+ disconnectedCallback() {
192
+ super.disconnectedCallback();
193
+ this.rowResizeObserver?.disconnect();
194
+ this.rowResizeObserver = undefined;
195
+ this.observedRows.clear();
196
+ this.containerResizeObserver?.disconnect();
197
+ this.containerResizeObserver = undefined;
198
+ if (this.scrollRafId !== undefined) {
199
+ cancelAnimationFrame(this.scrollRafId);
200
+ this.scrollRafId = undefined;
201
+ }
202
+ this.renderRoot.querySelector('[part="base"]')?.removeEventListener('scroll', this.onScroll);
203
+ }
204
+ firstUpdated() {
205
+ this.attachContainerListeners();
206
+ }
207
+ willUpdate(changed) {
208
+ this.isFirstUpdate = !this.hasUpdated;
209
+ if (changed.has('rowHeight')) {
210
+ this.fixedRowHeight = this.parseRowHeight(this.rowHeight);
211
+ }
212
+ this.recomputeOffsets();
213
+ this.computeRange();
214
+ }
215
+ updated(changed) {
216
+ super.updated(changed);
217
+ this.syncRowObservers();
218
+ if (changed.has('activeId') && !this.isFirstUpdate)
219
+ this.scrollActiveIntoView();
220
+ this.emitRangeChangeIfNeeded();
221
+ this.maybeFireLoadMore();
222
+ }
223
+ parseRowHeight(value) {
224
+ if (value === 'auto')
225
+ return null;
226
+ const n = Number(value);
227
+ // Anything that isn't 'auto' or a positive finite number falls back to
228
+ // auto mode rather than throwing or producing a zero/negative-height
229
+ // row -- matches this library's generally-permissive attribute parsing.
230
+ return Number.isFinite(n) && n > 0 ? n : null;
231
+ }
232
+ keyOf(item, index) {
233
+ return this.keyFunction ? this.keyFunction(item, index) : index;
234
+ }
235
+ recomputeOffsets() {
236
+ const n = this.items.length;
237
+ const offsets = new Array(n + 1);
238
+ offsets[0] = 0;
239
+ for (let i = 0; i < n; i++) {
240
+ const h = this.fixedRowHeight ??
241
+ this.measuredHeights.get(String(this.keyOf(this.items[i], i))) ??
242
+ DEFAULT_ROW_ESTIMATE_PX;
243
+ offsets[i + 1] = offsets[i] + h;
244
+ }
245
+ this.offsets = offsets;
246
+ }
247
+ /** First item index whose bottom edge is at/after `offset`. */
248
+ findIndexAtOrAfter(offset) {
249
+ const offsets = this.offsets;
250
+ let lo = 0;
251
+ let hi = offsets.length - 2;
252
+ while (lo < hi) {
253
+ const mid = (lo + hi) >> 1;
254
+ if (offsets[mid + 1] <= offset)
255
+ lo = mid + 1;
256
+ else
257
+ hi = mid;
258
+ }
259
+ return lo;
260
+ }
261
+ /** Last item index whose top edge is at/before `offset`. */
262
+ findIndexAtOrBefore(offset) {
263
+ const offsets = this.offsets;
264
+ let lo = 0;
265
+ let hi = offsets.length - 2;
266
+ while (lo < hi) {
267
+ const mid = (lo + hi + 1) >> 1;
268
+ if (offsets[mid] < offset)
269
+ lo = mid;
270
+ else
271
+ hi = mid - 1;
272
+ }
273
+ return lo;
274
+ }
275
+ computeRange() {
276
+ const n = this.items.length;
277
+ if (n === 0 || this.viewportHeight <= 0) {
278
+ this.visibleStart = 0;
279
+ this.visibleEnd = -1;
280
+ this.renderStart = 0;
281
+ this.renderEnd = -1;
282
+ return;
283
+ }
284
+ const viewTop = this.containerScrollTop;
285
+ const viewBottom = viewTop + this.viewportHeight;
286
+ this.visibleStart = this.findIndexAtOrAfter(viewTop);
287
+ this.visibleEnd = this.findIndexAtOrBefore(viewBottom);
288
+ this.renderStart = Math.max(0, this.visibleStart - this.overscan);
289
+ this.renderEnd = Math.min(n - 1, this.visibleEnd + this.overscan);
290
+ }
291
+ attachContainerListeners() {
292
+ const base = this.renderRoot.querySelector('[part="base"]');
293
+ if (!base)
294
+ return;
295
+ this.containerResizeObserver = new ResizeObserver((entries) => {
296
+ const entry = entries[0];
297
+ if (!entry)
298
+ return;
299
+ this.viewportHeight = entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height;
300
+ });
301
+ this.containerResizeObserver.observe(base);
302
+ base.addEventListener('scroll', this.onScroll, { passive: true });
303
+ // Read synchronously too -- ResizeObserver's first callback is
304
+ // asynchronous, so without this the very first render would otherwise
305
+ // sit at viewportHeight=0 (rendering no rows at all) until that callback
306
+ // eventually fires. This is called from firstUpdated(), so setting a
307
+ // reactive property here schedules a second update on top of the one
308
+ // that just finished -- Lit's dev-mode console flags that pattern, but
309
+ // it's the documented exception ("the next update can only be scheduled
310
+ // as a side effect of the previous update"): the container's real size
311
+ // genuinely isn't knowable until after the first layout.
312
+ this.viewportHeight = base.clientHeight;
313
+ this.containerScrollTop = base.scrollTop;
314
+ }
315
+ /** Keeps the row `ResizeObserver` watching exactly the currently-rendered
316
+ * rows in `row-height="auto"` mode -- rows that scroll out of the
317
+ * rendered window are unobserved so the observer doesn't accumulate
318
+ * references to detached elements it can never usefully report on again. */
319
+ syncRowObservers() {
320
+ const ro = this.rowResizeObserver;
321
+ if (!ro)
322
+ return;
323
+ if (this.fixedRowHeight != null) {
324
+ for (const el of this.observedRows.values())
325
+ ro.unobserve(el);
326
+ this.observedRows.clear();
327
+ return;
328
+ }
329
+ const current = new Map();
330
+ this.renderRoot.querySelectorAll('[part="row"]').forEach((el) => {
331
+ const key = el.dataset.rowKey;
332
+ if (key !== undefined)
333
+ current.set(key, el);
334
+ });
335
+ for (const [key, el] of this.observedRows) {
336
+ if (current.get(key) !== el) {
337
+ ro.unobserve(el);
338
+ this.observedRows.delete(key);
339
+ }
340
+ }
341
+ for (const [key, el] of current) {
342
+ if (!this.observedRows.has(key)) {
343
+ this.observedRows.set(key, el);
344
+ ro.observe(el);
345
+ }
346
+ }
347
+ }
348
+ scrollActiveIntoView() {
349
+ if (!this.activeId)
350
+ return;
351
+ const index = this.items.findIndex((item, i) => String(this.keyOf(item, i)) === this.activeId);
352
+ if (index < 0)
353
+ return;
354
+ const base = this.renderRoot.querySelector('[part="base"]');
355
+ if (!base)
356
+ return;
357
+ const top = this.offsets[index] ?? 0;
358
+ const bottom = this.offsets[index + 1] ?? top;
359
+ const viewTop = base.scrollTop;
360
+ const viewBottom = viewTop + base.clientHeight;
361
+ let target = null;
362
+ if (top < viewTop)
363
+ target = top;
364
+ else if (bottom > viewBottom)
365
+ target = bottom - base.clientHeight;
366
+ if (target === null)
367
+ return;
368
+ base.scrollTo({ top: Math.max(0, target), behavior: prefersReducedMotion() ? 'auto' : 'smooth' });
369
+ }
370
+ emitRangeChangeIfNeeded() {
371
+ if (this.visibleEnd < this.visibleStart)
372
+ return;
373
+ if (this.visibleStart === this.lastEmittedStart && this.visibleEnd === this.lastEmittedEnd)
374
+ return;
375
+ this.lastEmittedStart = this.visibleStart;
376
+ this.lastEmittedEnd = this.visibleEnd;
377
+ this.emit('lyra-visible-range-changed', {
378
+ start: this.visibleStart,
379
+ end: this.visibleEnd,
380
+ });
381
+ }
382
+ maybeFireLoadMore() {
383
+ const n = this.items.length;
384
+ const nearBottom = n > 0 && this.visibleEnd >= n - 1;
385
+ if (!nearBottom) {
386
+ this.loadMoreArmed = true;
387
+ return;
388
+ }
389
+ if (!this.hasMore || this.loading || !this.loadMoreArmed)
390
+ return;
391
+ this.loadMoreArmed = false;
392
+ this.emit('lyra-load-more');
393
+ }
394
+ renderRow(item, index, total) {
395
+ const key = String(this.keyOf(item, index));
396
+ const top = this.offsets[index] ?? 0;
397
+ const isActive = this.activeId !== '' && key === this.activeId;
398
+ return html `
399
+ <div
400
+ part="row"
401
+ role="listitem"
402
+ data-row-key=${key}
403
+ aria-setsize=${total}
404
+ aria-posinset=${index + 1}
405
+ aria-current=${isActive ? 'true' : nothing}
406
+ style=${styleMap({ transform: `translateY(${top}px)` })}
407
+ >
408
+ ${this.renderItem(item, index)}
409
+ </div>
410
+ `;
411
+ }
412
+ render() {
413
+ const n = this.items.length;
414
+ const totalHeight = this.offsets[n] ?? 0;
415
+ const windowed = [];
416
+ for (let i = this.renderStart; i <= this.renderEnd; i++) {
417
+ windowed.push({ item: this.items[i], index: i });
418
+ }
419
+ return html `
420
+ <div part="base" role="list" tabindex="0" aria-busy=${this.loading ? 'true' : nothing}>
421
+ <div part="spacer" style=${styleMap({ height: `${totalHeight}px` })}>
422
+ ${repeat(windowed, (w) => this.keyOf(w.item, w.index), (w) => this.renderRow(w.item, w.index, n))}
423
+ </div>
424
+ </div>
425
+ `;
426
+ }
427
+ }
428
+ __decorate([
429
+ property({ attribute: false })
430
+ ], LyraVirtualList.prototype, "items", void 0);
431
+ __decorate([
432
+ property({ attribute: false })
433
+ ], LyraVirtualList.prototype, "renderItem", void 0);
434
+ __decorate([
435
+ property({ attribute: false })
436
+ ], LyraVirtualList.prototype, "keyFunction", void 0);
437
+ __decorate([
438
+ property({ attribute: false })
439
+ ], LyraVirtualList.prototype, "groups", void 0);
440
+ __decorate([
441
+ property({ attribute: 'row-height' })
442
+ ], LyraVirtualList.prototype, "rowHeight", void 0);
443
+ __decorate([
444
+ property({ type: Number })
445
+ ], LyraVirtualList.prototype, "overscan", void 0);
446
+ __decorate([
447
+ property({ attribute: 'active-id' })
448
+ ], LyraVirtualList.prototype, "activeId", void 0);
449
+ __decorate([
450
+ property({ type: Boolean, reflect: true })
451
+ ], LyraVirtualList.prototype, "loading", void 0);
452
+ __decorate([
453
+ property({ type: Boolean, attribute: 'has-more', reflect: true })
454
+ ], LyraVirtualList.prototype, "hasMore", void 0);
455
+ __decorate([
456
+ state()
457
+ ], LyraVirtualList.prototype, "containerScrollTop", void 0);
458
+ __decorate([
459
+ state()
460
+ ], LyraVirtualList.prototype, "viewportHeight", void 0);
461
+ defineElement('virtual-list', LyraVirtualList);
@@ -0,0 +1 @@
1
+ export declare const styles: import("lit").CSSResult;
@@ -0,0 +1,44 @@
1
+ import { css } from 'lit';
2
+ export const styles = css `
3
+ :host {
4
+ display: block;
5
+ /* Consumer-tunable viewport height, same pattern as --lyra-chart-height --
6
+ a virtualized list is meaningless without a bounded scroll extent, so
7
+ this ships a sane default rather than collapsing to 0 when a caller
8
+ forgets to size the host. */
9
+ --lyra-virtual-list-height: 24rem;
10
+ }
11
+ [part='base'] {
12
+ position: relative;
13
+ block-size: var(--lyra-virtual-list-height);
14
+ overflow-x: hidden;
15
+ overflow-y: auto;
16
+ /* A fast fling shouldn't also scroll the page behind this list once it
17
+ hits either end. */
18
+ overscroll-behavior: contain;
19
+ }
20
+ [part='base']:focus-visible {
21
+ outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
22
+ /* Negative (inward) so the ring isn't clipped by this element's own
23
+ overflow:auto -- an outward ring (every other component's convention)
24
+ would otherwise be cut off along the scrolling edges. */
25
+ outline-offset: calc(-1 * var(--lyra-focus-ring-offset));
26
+ }
27
+ [part='spacer'] {
28
+ position: relative;
29
+ inline-size: 100%;
30
+ }
31
+ [part='row'] {
32
+ position: absolute;
33
+ inset-inline-start: 0;
34
+ inset-block-start: 0;
35
+ inline-size: 100%;
36
+ box-sizing: border-box;
37
+ /* Every row's position updates via this transform on every scroll-driven
38
+ re-render -- hinting the compositor avoids a full repaint per frame. */
39
+ will-change: transform;
40
+ }
41
+ :host([loading]) [part='base'] {
42
+ cursor: progress;
43
+ }
44
+ `;
@@ -21,6 +21,10 @@ import { LyraElement } from '../../internal/lyra-element.js';
21
21
  * @csspart fullscreen-button - The fullscreen toggle button.
22
22
  * @csspart body - The wrapper around the default slot (the panel body).
23
23
  * @csspart backdrop - The fullscreen scrim behind the panel.
24
+ *
25
+ * `fullscreen-inset` overrides the default `var(--lyra-space-l)` inset applied to `[part="base"]`
26
+ * and `[part="backdrop"]` while fullscreen (e.g. `"0 0 0 240px"` to leave a persistent sidebar
27
+ * visible). `compact` tightens header/body padding — same convention as `lyra-empty`'s `compact`.
24
28
  */
25
29
  export declare class LyraWidget extends LyraElement {
26
30
  static styles: import("lit").CSSResultGroup[];
@@ -30,6 +34,12 @@ export declare class LyraWidget extends LyraElement {
30
34
  collapsed: boolean;
31
35
  expandable: boolean;
32
36
  fullscreen: boolean;
37
+ /** Raw CSS `inset` shorthand applied to the fullscreen panel and backdrop instead of the default
38
+ * `var(--lyra-space-l)` on every side — e.g. `"0 0 0 240px"` to leave a 240px persistent sidebar
39
+ * visible while fullscreen. */
40
+ fullscreenInset: string;
41
+ /** Tighter header/body padding for constrained spaces. */
42
+ compact: boolean;
33
43
  private hasActionsSlot;
34
44
  private releaseScrollLock?;
35
45
  private lastTrigger?;
@@ -69,6 +69,10 @@ function isRendered(el) {
69
69
  * @csspart fullscreen-button - The fullscreen toggle button.
70
70
  * @csspart body - The wrapper around the default slot (the panel body).
71
71
  * @csspart backdrop - The fullscreen scrim behind the panel.
72
+ *
73
+ * `fullscreen-inset` overrides the default `var(--lyra-space-l)` inset applied to `[part="base"]`
74
+ * and `[part="backdrop"]` while fullscreen (e.g. `"0 0 0 240px"` to leave a persistent sidebar
75
+ * visible). `compact` tightens header/body padding — same convention as `lyra-empty`'s `compact`.
72
76
  */
73
77
  export class LyraWidget extends LyraElement {
74
78
  constructor() {
@@ -79,6 +83,12 @@ export class LyraWidget extends LyraElement {
79
83
  this.collapsed = false;
80
84
  this.expandable = false;
81
85
  this.fullscreen = false;
86
+ /** Raw CSS `inset` shorthand applied to the fullscreen panel and backdrop instead of the default
87
+ * `var(--lyra-space-l)` on every side — e.g. `"0 0 0 240px"` to leave a 240px persistent sidebar
88
+ * visible while fullscreen. */
89
+ this.fullscreenInset = '';
90
+ /** Tighter header/body padding for constrained spaces. */
91
+ this.compact = false;
82
92
  this.hasActionsSlot = false;
83
93
  this.bodyId = nextId('widget-body');
84
94
  this.onActionsSlotChange = (e) => {
@@ -221,13 +231,20 @@ export class LyraWidget extends LyraElement {
221
231
  const hasLabel = this.label.length > 0;
222
232
  const hasSublabel = this.sublabel.length > 0;
223
233
  return html `
224
- ${this.fullscreen ? html `<div part="backdrop" @click=${this.onBackdropClick}></div>` : nothing}
234
+ ${this.fullscreen
235
+ ? html `<div
236
+ part="backdrop"
237
+ style=${this.fullscreenInset ? `--lyra-widget-fullscreen-inset:${this.fullscreenInset}` : nothing}
238
+ @click=${this.onBackdropClick}
239
+ ></div>`
240
+ : nothing}
225
241
  <div
226
242
  part="base"
227
243
  role=${this.fullscreen ? 'dialog' : nothing}
228
244
  aria-modal=${this.fullscreen ? 'true' : nothing}
229
245
  aria-label=${this.fullscreen ? (hasLabel ? this.label : 'Fullscreen panel') : nothing}
230
246
  tabindex=${this.fullscreen ? '-1' : nothing}
247
+ style=${this.fullscreenInset ? `--lyra-widget-fullscreen-inset:${this.fullscreenInset}` : nothing}
231
248
  >
232
249
  <div part="header">
233
250
  <div part="title">
@@ -288,6 +305,12 @@ __decorate([
288
305
  __decorate([
289
306
  property({ type: Boolean, reflect: true })
290
307
  ], LyraWidget.prototype, "fullscreen", void 0);
308
+ __decorate([
309
+ property({ attribute: 'fullscreen-inset' })
310
+ ], LyraWidget.prototype, "fullscreenInset", void 0);
311
+ __decorate([
312
+ property({ type: Boolean, reflect: true })
313
+ ], LyraWidget.prototype, "compact", void 0);
291
314
  __decorate([
292
315
  state()
293
316
  ], LyraWidget.prototype, "hasActionsSlot", void 0);
@@ -6,6 +6,7 @@ export const styles = css `
6
6
  without a raw literal leaking into the public API (no shared
7
7
  --wa-*-overlay token exists in the design system to resolve through). */
8
8
  --lyra-widget-overlay-color: rgb(0 0 0 / 0.5);
9
+ --lyra-widget-fullscreen-inset: var(--lyra-space-l);
9
10
  }
10
11
  [part='base'] {
11
12
  display: flex;
@@ -77,13 +78,13 @@ export const styles = css `
77
78
  }
78
79
  [part='backdrop'] {
79
80
  position: fixed;
80
- inset: 0;
81
+ inset: var(--lyra-widget-fullscreen-inset, 0);
81
82
  background: var(--lyra-widget-overlay-color);
82
83
  z-index: 999;
83
84
  }
84
85
  :host([fullscreen]) [part='base'] {
85
86
  position: fixed;
86
- inset: var(--lyra-space-l);
87
+ inset: var(--lyra-widget-fullscreen-inset);
87
88
  z-index: 1000;
88
89
  box-shadow: var(--lyra-shadow);
89
90
  }
@@ -91,6 +92,12 @@ export const styles = css `
91
92
  overflow: auto;
92
93
  block-size: 100%;
93
94
  }
95
+ :host([compact]) [part='header'] {
96
+ padding: var(--lyra-space-xs) var(--lyra-space-s);
97
+ }
98
+ :host([compact]) [part='body'] {
99
+ padding: var(--lyra-space-s);
100
+ }
94
101
  @media (prefers-reduced-motion: reduce) {
95
102
  [part='collapse-button'],
96
103
  [part='fullscreen-button'] {
@@ -9,6 +9,18 @@ const RADIUS_STEP_PER_RADIAN = 3;
9
9
  * generous enough that only a pathological input (e.g. one giant word
10
10
  * repeated many times) ever exhausts it. */
11
11
  const MAX_RADIUS_AREA_FACTOR = 6;
12
+ /** Fallback used by `resolveFontSizeBounds()` for any non-finite/non-positive
13
+ * `minFontSize`/`maxFontSize` input. */
14
+ const MIN_SANE_FONT_SIZE = 1;
15
+ /** Normalizes possibly-invalid minFontSize/maxFontSize into a finite,
16
+ * positive, correctly-ordered pair — non-finite/negative inputs fall back
17
+ * to MIN_SANE_FONT_SIZE, and a reversed pair (max < min) is swapped rather
18
+ * than left to invert the weight-to-size mapping. */
19
+ function resolveFontSizeBounds(minFontSize, maxFontSize) {
20
+ const min = Number.isFinite(minFontSize) && minFontSize > 0 ? minFontSize : MIN_SANE_FONT_SIZE;
21
+ const max = Number.isFinite(maxFontSize) && maxFontSize > 0 ? maxFontSize : MIN_SANE_FONT_SIZE;
22
+ return min <= max ? [min, max] : [max, min];
23
+ }
12
24
  /** Clamps a (possibly negative/non-finite) input weight for scale math only —
13
25
  * never fed back to callers, who should still see their own original `weight`. */
14
26
  function effectiveWeight(weight) {
@@ -29,7 +41,8 @@ function rectsOverlap(ax, ay, aw, ah, bx, by, bw, bh) {
29
41
  * any word already placed). Deterministic given a deterministic `random`.
30
42
  */
31
43
  export function layoutWordCloud(words, options) {
32
- const { minFontSize, maxFontSize, scale, orientations, measureText } = options;
44
+ const { scale, orientations, measureText } = options;
45
+ const [minFontSize, maxFontSize] = resolveFontSizeBounds(options.minFontSize, options.maxFontSize);
33
46
  const random = options.random ?? Math.random;
34
47
  const skipped = [];
35
48
  const decorated = words
@@ -50,6 +50,12 @@ export declare class LyraWordCloud extends LyraElement {
50
50
  * independent of the weight-sorted placement order. */
51
51
  private navOrder;
52
52
  protected willUpdate(changed: PropertyValues): void;
53
+ private relayout;
54
+ /** Forces a relayout so the font-family theme token (`--lyra-font`) is
55
+ * re-read from computed style — mirrors `lyra-chart`'s `refreshTheme()`.
56
+ * No global theme-broadcast event exists in lyra-ui to subscribe to
57
+ * automatically; call this from a consumer's own theme-toggle handler. */
58
+ refreshTheme(): void;
53
59
  private activate;
54
60
  private announce;
55
61
  private onWordClick;