@aceshooting/lyra-ui 1.2.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/README.md +98 -14
  2. package/custom-elements.json +30279 -12124
  3. package/dist/components/app-rail/app-rail-item.d.ts +30 -0
  4. package/dist/components/app-rail/app-rail-item.js +68 -0
  5. package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail-item.styles.js +65 -0
  7. package/dist/components/app-rail/app-rail.d.ts +168 -0
  8. package/dist/components/app-rail/app-rail.js +419 -0
  9. package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
  10. package/dist/components/app-rail/app-rail.styles.js +128 -0
  11. package/dist/components/attachment-chip/attachment-chip.d.ts +141 -0
  12. package/dist/components/attachment-chip/attachment-chip.js +356 -0
  13. package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
  14. package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
  15. package/dist/components/attachment-trigger/attachment-trigger.d.ts +96 -0
  16. package/dist/components/attachment-trigger/attachment-trigger.js +270 -0
  17. package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
  18. package/dist/components/attachment-trigger/attachment-trigger.styles.js +90 -0
  19. package/dist/components/chart/bar-chart.js +2 -18
  20. package/dist/components/chart/box-plot.d.ts +25 -1
  21. package/dist/components/chart/box-plot.js +147 -7
  22. package/dist/components/chart/box-plot.styles.js +13 -0
  23. package/dist/components/chart/bubble-chart.js +2 -18
  24. package/dist/components/chart/chart-loader.d.ts +44 -13
  25. package/dist/components/chart/chart-loader.js +65 -18
  26. package/dist/components/chart/chart.d.ts +55 -12
  27. package/dist/components/chart/chart.js +247 -49
  28. package/dist/components/chart/doughnut-chart.js +2 -18
  29. package/dist/components/chart/histogram-bin.d.ts +7 -1
  30. package/dist/components/chart/histogram-bin.js +32 -14
  31. package/dist/components/chart/histogram.js +8 -16
  32. package/dist/components/chart/line-chart.js +2 -18
  33. package/dist/components/chart/lite-chart.d.ts +134 -3
  34. package/dist/components/chart/lite-chart.js +382 -67
  35. package/dist/components/chart/lite-chart.styles.js +9 -0
  36. package/dist/components/chart/pie-chart.js +2 -18
  37. package/dist/components/chart/polar-area-chart.js +2 -18
  38. package/dist/components/chart/radar-chart.js +2 -18
  39. package/dist/components/chart/scatter-chart.js +2 -18
  40. package/dist/components/chat-composer/chat-composer.d.ts +133 -0
  41. package/dist/components/chat-composer/chat-composer.js +366 -0
  42. package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
  43. package/dist/components/chat-composer/chat-composer.styles.js +145 -0
  44. package/dist/components/chat-message/chat-message.d.ts +141 -0
  45. package/dist/components/chat-message/chat-message.js +331 -0
  46. package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
  47. package/dist/components/chat-message/chat-message.styles.js +203 -0
  48. package/dist/components/checkbox/checkbox.d.ts +117 -0
  49. package/dist/components/checkbox/checkbox.js +353 -0
  50. package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
  51. package/dist/components/checkbox/checkbox.styles.js +77 -0
  52. package/dist/components/chip/chip-group.d.ts +56 -0
  53. package/dist/components/chip/chip-group.js +130 -0
  54. package/dist/components/chip/chip-group.styles.d.ts +1 -0
  55. package/dist/components/chip/chip-group.styles.js +57 -0
  56. package/dist/components/chip/chip.d.ts +64 -0
  57. package/dist/components/chip/chip.js +122 -0
  58. package/dist/components/chip/chip.styles.d.ts +1 -0
  59. package/dist/components/chip/chip.styles.js +115 -0
  60. package/dist/components/citation-badge/citation-badge.d.ts +113 -0
  61. package/dist/components/citation-badge/citation-badge.js +318 -0
  62. package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
  63. package/dist/components/citation-badge/citation-badge.styles.js +96 -0
  64. package/dist/components/code-block/code-block.d.ts +127 -0
  65. package/dist/components/code-block/code-block.js +382 -0
  66. package/dist/components/code-block/code-block.styles.d.ts +1 -0
  67. package/dist/components/code-block/code-block.styles.js +187 -0
  68. package/dist/components/code-block/code-loader.d.ts +87 -0
  69. package/dist/components/code-block/code-loader.js +142 -0
  70. package/dist/components/combobox/combobox.d.ts +65 -6
  71. package/dist/components/combobox/combobox.js +258 -48
  72. package/dist/components/combobox/combobox.styles.js +3 -3
  73. package/dist/components/combobox/option.d.ts +5 -1
  74. package/dist/components/combobox/option.js +35 -0
  75. package/dist/components/context-meter/context-meter.d.ts +53 -0
  76. package/dist/components/context-meter/context-meter.js +159 -0
  77. package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
  78. package/dist/components/context-meter/context-meter.styles.js +114 -0
  79. package/dist/components/conversation-item/conversation-item.d.ts +125 -0
  80. package/dist/components/conversation-item/conversation-item.js +331 -0
  81. package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
  82. package/dist/components/conversation-item/conversation-item.styles.js +155 -0
  83. package/dist/components/date-picker/calendar-core.d.ts +24 -0
  84. package/dist/components/date-picker/calendar-core.js +51 -4
  85. package/dist/components/date-picker/date-input.d.ts +100 -9
  86. package/dist/components/date-picker/date-input.js +383 -66
  87. package/dist/components/date-picker/date-picker.d.ts +35 -4
  88. package/dist/components/date-picker/date-picker.js +171 -44
  89. package/dist/components/dialog/confirm.d.ts +40 -0
  90. package/dist/components/dialog/confirm.js +76 -0
  91. package/dist/components/dialog/dialog.d.ts +129 -0
  92. package/dist/components/dialog/dialog.js +288 -0
  93. package/dist/components/dialog/dialog.styles.d.ts +1 -0
  94. package/dist/components/dialog/dialog.styles.js +96 -0
  95. package/dist/components/dock-panel/dock-panel.d.ts +142 -0
  96. package/dist/components/dock-panel/dock-panel.js +359 -0
  97. package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
  98. package/dist/components/dock-panel/dock-panel.styles.js +159 -0
  99. package/dist/components/document-preview/document-preview.d.ts +143 -0
  100. package/dist/components/document-preview/document-preview.js +388 -0
  101. package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
  102. package/dist/components/document-preview/document-preview.styles.js +191 -0
  103. package/dist/components/empty/empty.d.ts +1 -2
  104. package/dist/components/empty/empty.js +18 -12
  105. package/dist/components/empty/empty.styles.js +0 -3
  106. package/dist/components/export-button/csv.js +1 -1
  107. package/dist/components/export-button/export-button.d.ts +12 -0
  108. package/dist/components/export-button/export-button.js +35 -5
  109. package/dist/components/export-button/export-button.styles.js +5 -1
  110. package/dist/components/file-input/accept.js +2 -0
  111. package/dist/components/file-input/file-input.d.ts +10 -1
  112. package/dist/components/file-input/file-input.js +36 -5
  113. package/dist/components/flag/flag.d.ts +29 -13
  114. package/dist/components/flag/flag.js +54 -14
  115. package/dist/components/flag/flag.styles.js +1 -1
  116. package/dist/components/flag/language-map.d.ts +4 -1
  117. package/dist/components/flag/language-map.js +6 -3
  118. package/dist/components/gauge/gauge.d.ts +10 -1
  119. package/dist/components/gauge/gauge.js +41 -13
  120. package/dist/components/generation-status/generation-status.d.ts +117 -0
  121. package/dist/components/generation-status/generation-status.js +327 -0
  122. package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
  123. package/dist/components/generation-status/generation-status.styles.js +84 -0
  124. package/dist/components/graph/graph.d.ts +37 -3
  125. package/dist/components/graph/graph.js +132 -20
  126. package/dist/components/heatmap/calendar-grid.d.ts +19 -7
  127. package/dist/components/heatmap/calendar-grid.js +42 -18
  128. package/dist/components/heatmap/heatmap-scale.d.ts +11 -1
  129. package/dist/components/heatmap/heatmap-scale.js +14 -2
  130. package/dist/components/heatmap/heatmap.d.ts +227 -12
  131. package/dist/components/heatmap/heatmap.js +488 -93
  132. package/dist/components/json-viewer/json-viewer.d.ts +70 -0
  133. package/dist/components/json-viewer/json-viewer.js +361 -0
  134. package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
  135. package/dist/components/json-viewer/json-viewer.styles.js +177 -0
  136. package/dist/components/kbd/kbd.d.ts +77 -0
  137. package/dist/components/kbd/kbd.js +231 -0
  138. package/dist/components/kbd/kbd.styles.d.ts +1 -0
  139. package/dist/components/kbd/kbd.styles.js +52 -0
  140. package/dist/components/live-region/live-region.d.ts +90 -0
  141. package/dist/components/live-region/live-region.js +189 -0
  142. package/dist/components/live-region/live-region.styles.d.ts +1 -0
  143. package/dist/components/live-region/live-region.styles.js +10 -0
  144. package/dist/components/map/map.d.ts +32 -7
  145. package/dist/components/map/map.js +133 -32
  146. package/dist/components/markdown/markdown-loader.d.ts +58 -0
  147. package/dist/components/markdown/markdown-loader.js +77 -0
  148. package/dist/components/markdown/markdown.d.ts +119 -0
  149. package/dist/components/markdown/markdown.js +389 -0
  150. package/dist/components/markdown/markdown.styles.d.ts +1 -0
  151. package/dist/components/markdown/markdown.styles.js +88 -0
  152. package/dist/components/media-card/media-card.d.ts +130 -0
  153. package/dist/components/media-card/media-card.js +273 -0
  154. package/dist/components/media-card/media-card.styles.d.ts +1 -0
  155. package/dist/components/media-card/media-card.styles.js +132 -0
  156. package/dist/components/mention-popover/mention-popover.d.ts +203 -0
  157. package/dist/components/mention-popover/mention-popover.js +493 -0
  158. package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
  159. package/dist/components/mention-popover/mention-popover.styles.js +101 -0
  160. package/dist/components/menu/menu-item.d.ts +91 -0
  161. package/dist/components/menu/menu-item.js +206 -0
  162. package/dist/components/menu/menu-item.styles.d.ts +1 -0
  163. package/dist/components/menu/menu-item.styles.js +75 -0
  164. package/dist/components/menu/menu.d.ts +167 -0
  165. package/dist/components/menu/menu.js +461 -0
  166. package/dist/components/menu/menu.styles.d.ts +1 -0
  167. package/dist/components/menu/menu.styles.js +67 -0
  168. package/dist/components/model-select/model-select.d.ts +170 -0
  169. package/dist/components/model-select/model-select.js +588 -0
  170. package/dist/components/model-select/model-select.styles.d.ts +1 -0
  171. package/dist/components/model-select/model-select.styles.js +203 -0
  172. package/dist/components/model-settings-panel/model-settings-panel.d.ts +93 -0
  173. package/dist/components/model-settings-panel/model-settings-panel.js +209 -0
  174. package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
  175. package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
  176. package/dist/components/playback/playback.d.ts +19 -3
  177. package/dist/components/playback/playback.js +109 -33
  178. package/dist/components/playback/playback.styles.js +6 -1
  179. package/dist/components/responsive-panel/responsive-panel.d.ts +163 -0
  180. package/dist/components/responsive-panel/responsive-panel.js +363 -0
  181. package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
  182. package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
  183. package/dist/components/result-card/result-card.d.ts +50 -0
  184. package/dist/components/result-card/result-card.js +89 -0
  185. package/dist/components/result-card/result-card.styles.d.ts +1 -0
  186. package/dist/components/result-card/result-card.styles.js +49 -0
  187. package/dist/components/result-card/result-field.d.ts +36 -0
  188. package/dist/components/result-card/result-field.js +87 -0
  189. package/dist/components/result-card/result-field.styles.d.ts +1 -0
  190. package/dist/components/result-card/result-field.styles.js +32 -0
  191. package/dist/components/select/select.d.ts +84 -4
  192. package/dist/components/select/select.js +251 -36
  193. package/dist/components/skeleton/skeleton.d.ts +3 -0
  194. package/dist/components/skeleton/skeleton.js +7 -1
  195. package/dist/components/skeleton/skeleton.styles.js +5 -4
  196. package/dist/components/slider/slider.d.ts +141 -0
  197. package/dist/components/slider/slider.js +467 -0
  198. package/dist/components/slider/slider.styles.d.ts +1 -0
  199. package/dist/components/slider/slider.styles.js +87 -0
  200. package/dist/components/source-card/source-card.d.ts +104 -0
  201. package/dist/components/source-card/source-card.js +195 -0
  202. package/dist/components/source-card/source-card.styles.d.ts +1 -0
  203. package/dist/components/source-card/source-card.styles.js +69 -0
  204. package/dist/components/source-list/source-list.d.ts +63 -0
  205. package/dist/components/source-list/source-list.js +130 -0
  206. package/dist/components/source-list/source-list.styles.d.ts +1 -0
  207. package/dist/components/source-list/source-list.styles.js +59 -0
  208. package/dist/components/sparkline/sparkline.js +58 -20
  209. package/dist/components/split/split.d.ts +224 -5
  210. package/dist/components/split/split.js +617 -43
  211. package/dist/components/split/split.styles.js +47 -0
  212. package/dist/components/stat/stat.d.ts +15 -4
  213. package/dist/components/stat/stat.js +53 -12
  214. package/dist/components/stream-status/stream-status.d.ts +126 -0
  215. package/dist/components/stream-status/stream-status.js +292 -0
  216. package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
  217. package/dist/components/stream-status/stream-status.styles.js +103 -0
  218. package/dist/components/streaming-text/streaming-text.d.ts +104 -0
  219. package/dist/components/streaming-text/streaming-text.js +224 -0
  220. package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
  221. package/dist/components/streaming-text/streaming-text.styles.js +63 -0
  222. package/dist/components/switch/switch.d.ts +103 -0
  223. package/dist/components/switch/switch.js +250 -0
  224. package/dist/components/switch/switch.styles.d.ts +1 -0
  225. package/dist/components/switch/switch.styles.js +75 -0
  226. package/dist/components/table/table.d.ts +89 -5
  227. package/dist/components/table/table.js +243 -26
  228. package/dist/components/table/table.styles.js +6 -1
  229. package/dist/components/tabs/tabs.d.ts +74 -0
  230. package/dist/components/tabs/tabs.js +254 -0
  231. package/dist/components/tabs/tabs.styles.d.ts +1 -0
  232. package/dist/components/tabs/tabs.styles.js +74 -0
  233. package/dist/components/thinking-panel/thinking-panel.d.ts +123 -0
  234. package/dist/components/thinking-panel/thinking-panel.js +260 -0
  235. package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
  236. package/dist/components/thinking-panel/thinking-panel.styles.js +123 -0
  237. package/dist/components/time-range/time-range.d.ts +59 -2
  238. package/dist/components/time-range/time-range.js +163 -67
  239. package/dist/components/toast/toast-item.d.ts +12 -2
  240. package/dist/components/toast/toast-item.js +106 -44
  241. package/dist/components/toast/toast-item.styles.js +59 -28
  242. package/dist/components/toast/toast.js +17 -5
  243. package/dist/components/toast/toaster.js +10 -1
  244. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +131 -0
  245. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +329 -0
  246. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
  247. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
  248. package/dist/components/tool-call-chip/tool-call-chip.d.ts +105 -0
  249. package/dist/components/tool-call-chip/tool-call-chip.js +349 -0
  250. package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
  251. package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
  252. package/dist/components/tool-param-form/tool-param-form.d.ts +206 -0
  253. package/dist/components/tool-param-form/tool-param-form.js +610 -0
  254. package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
  255. package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
  256. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +122 -0
  257. package/dist/components/tool-result-dialog/tool-result-dialog.js +358 -0
  258. package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
  259. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
  260. package/dist/components/tool-result-view/registry.d.ts +73 -0
  261. package/dist/components/tool-result-view/registry.js +89 -0
  262. package/dist/components/tool-result-view/tool-result-view.d.ts +58 -0
  263. package/dist/components/tool-result-view/tool-result-view.js +152 -0
  264. package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
  265. package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
  266. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
  267. package/dist/components/tool-select-dialog/tool-select-dialog.js +350 -0
  268. package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
  269. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +191 -0
  270. package/dist/components/tree/tree-node.d.ts +15 -3
  271. package/dist/components/tree/tree-node.js +20 -7
  272. package/dist/components/tree/tree.d.ts +25 -10
  273. package/dist/components/tree/tree.js +39 -31
  274. package/dist/components/typing-indicator/typing-indicator.d.ts +70 -0
  275. package/dist/components/typing-indicator/typing-indicator.js +108 -0
  276. package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
  277. package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
  278. package/dist/components/virtual-list/virtual-list.d.ts +210 -0
  279. package/dist/components/virtual-list/virtual-list.js +607 -0
  280. package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
  281. package/dist/components/virtual-list/virtual-list.styles.js +56 -0
  282. package/dist/components/widget/widget.d.ts +5 -4
  283. package/dist/components/widget/widget.js +54 -120
  284. package/dist/components/widget/widget.styles.js +8 -2
  285. package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
  286. package/dist/components/word-cloud/word-cloud-layout.js +29 -2
  287. package/dist/components/word-cloud/word-cloud.d.ts +28 -2
  288. package/dist/components/word-cloud/word-cloud.js +69 -19
  289. package/dist/components/word-cloud/word-cloud.styles.js +16 -3
  290. package/dist/internal/anchored-validity.d.ts +1 -0
  291. package/dist/internal/anchored-validity.js +86 -0
  292. package/dist/internal/announcer.d.ts +57 -0
  293. package/dist/internal/announcer.js +71 -0
  294. package/dist/internal/form-associated.d.ts +8 -0
  295. package/dist/internal/form-associated.js +98 -15
  296. package/dist/internal/group-by-recency.d.ts +50 -0
  297. package/dist/internal/group-by-recency.js +80 -0
  298. package/dist/internal/numbers.d.ts +12 -0
  299. package/dist/internal/numbers.js +26 -0
  300. package/dist/internal/overlay-manager.d.ts +51 -0
  301. package/dist/internal/overlay-manager.js +523 -0
  302. package/dist/internal/positioner.js +27 -3
  303. package/dist/internal/rtl.d.ts +23 -0
  304. package/dist/internal/rtl.js +28 -0
  305. package/dist/internal/safe-url.d.ts +12 -0
  306. package/dist/internal/safe-url.js +41 -0
  307. package/dist/internal/scroll-lock.d.ts +10 -5
  308. package/dist/internal/scroll-lock.js +30 -14
  309. package/dist/internal/tokens.styles.js +22 -10
  310. package/dist/lyra.d.ts +133 -31
  311. package/dist/lyra.js +96 -26
  312. package/llms-full.txt +4546 -183
  313. package/llms.txt +21 -5
  314. package/package.json +41 -6
  315. package/dist/components/chart/bar-chart.stories.d.ts +0 -5
  316. package/dist/components/chart/bar-chart.stories.js +0 -20
  317. package/dist/components/chart/box-plot.stories.d.ts +0 -5
  318. package/dist/components/chart/box-plot.stories.js +0 -29
  319. package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
  320. package/dist/components/chart/bubble-chart.stories.js +0 -26
  321. package/dist/components/chart/chart.stories.d.ts +0 -32
  322. package/dist/components/chart/chart.stories.js +0 -141
  323. package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
  324. package/dist/components/chart/doughnut-chart.stories.js +0 -26
  325. package/dist/components/chart/histogram.stories.d.ts +0 -5
  326. package/dist/components/chart/histogram.stories.js +0 -17
  327. package/dist/components/chart/line-chart.stories.d.ts +0 -22
  328. package/dist/components/chart/line-chart.stories.js +0 -99
  329. package/dist/components/chart/lite-chart.stories.d.ts +0 -14
  330. package/dist/components/chart/lite-chart.stories.js +0 -114
  331. package/dist/components/chart/pie-chart.stories.d.ts +0 -5
  332. package/dist/components/chart/pie-chart.stories.js +0 -26
  333. package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
  334. package/dist/components/chart/polar-area-chart.stories.js +0 -20
  335. package/dist/components/chart/radar-chart.stories.d.ts +0 -5
  336. package/dist/components/chart/radar-chart.stories.js +0 -20
  337. package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
  338. package/dist/components/chart/scatter-chart.stories.js +0 -31
  339. package/dist/components/combobox/combobox.stories.d.ts +0 -24
  340. package/dist/components/combobox/combobox.stories.js +0 -102
  341. package/dist/components/date-picker/date-input.stories.d.ts +0 -10
  342. package/dist/components/date-picker/date-input.stories.js +0 -48
  343. package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
  344. package/dist/components/date-picker/date-picker.stories.js +0 -25
  345. package/dist/components/empty/empty.stories.d.ts +0 -7
  346. package/dist/components/empty/empty.stories.js +0 -34
  347. package/dist/components/export-button/export-button.stories.d.ts +0 -7
  348. package/dist/components/export-button/export-button.stories.js +0 -37
  349. package/dist/components/file-input/file-input.stories.d.ts +0 -7
  350. package/dist/components/file-input/file-input.stories.js +0 -19
  351. package/dist/components/flag/flag.stories.d.ts +0 -6
  352. package/dist/components/flag/flag.stories.js +0 -31
  353. package/dist/components/gauge/gauge.stories.d.ts +0 -8
  354. package/dist/components/gauge/gauge.stories.js +0 -19
  355. package/dist/components/graph/graph.stories.d.ts +0 -8
  356. package/dist/components/graph/graph.stories.js +0 -68
  357. package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
  358. package/dist/components/heatmap/heatmap.stories.js +0 -179
  359. package/dist/components/map/map.stories.d.ts +0 -15
  360. package/dist/components/map/map.stories.js +0 -135
  361. package/dist/components/playback/playback.stories.d.ts +0 -7
  362. package/dist/components/playback/playback.stories.js +0 -16
  363. package/dist/components/select/select.stories.d.ts +0 -21
  364. package/dist/components/select/select.stories.js +0 -91
  365. package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
  366. package/dist/components/skeleton/skeleton.stories.js +0 -16
  367. package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
  368. package/dist/components/sparkline/sparkline.stories.js +0 -39
  369. package/dist/components/split/split.stories.d.ts +0 -7
  370. package/dist/components/split/split.stories.js +0 -36
  371. package/dist/components/stat/stat.stories.d.ts +0 -9
  372. package/dist/components/stat/stat.stories.js +0 -81
  373. package/dist/components/table/table.stories.d.ts +0 -12
  374. package/dist/components/table/table.stories.js +0 -67
  375. package/dist/components/time-range/time-range.stories.d.ts +0 -8
  376. package/dist/components/time-range/time-range.stories.js +0 -26
  377. package/dist/components/toast/toast.stories.d.ts +0 -8
  378. package/dist/components/toast/toast.stories.js +0 -72
  379. package/dist/components/tree/tree.stories.d.ts +0 -9
  380. package/dist/components/tree/tree.stories.js +0 -52
  381. package/dist/components/widget/widget.stories.d.ts +0 -9
  382. package/dist/components/widget/widget.stories.js +0 -74
  383. package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
  384. package/dist/components/word-cloud/word-cloud.stories.js +0 -55
@@ -8,6 +8,7 @@ import { html, svg, nothing } from 'lit';
8
8
  import { property, state, query } from 'lit/decorators.js';
9
9
  import { LyraElement } from '../../internal/lyra-element.js';
10
10
  import { defineElement } from '../../internal/prefix.js';
11
+ import { srOnly } from '../../internal/a11y.js';
11
12
  import { styles } from './lite-chart.styles.js';
12
13
  // Colorblind-considered categorical palette, used round-robin when a Series
13
14
  // doesn't set its own `color` — same role as Chart.js's default dataset
@@ -30,6 +31,7 @@ const AXIS_TITLE_SPACE = 14;
30
31
  const TICK_COUNT = 4;
31
32
  const BAR_GROUP_GAP = 0.2; // fraction of a category slot left as gap between categories
32
33
  const BAR_GAP = 0.08; // fraction of a category slot left as gap between grouped bars
34
+ const BAR_CORNER_RADIUS = 4; // px, used only when roundedBars is true
33
35
  /**
34
36
  * Picks a "nice" (1/2/5 × 10^n) step size for an axis spanning `span` over
35
37
  * roughly `count` ticks — the standard Heckbert nice-numbers approach, so
@@ -75,6 +77,33 @@ function niceDomain(dataLo, dataHi, beginAtZero, count) {
75
77
  * `getComputedStyle()`-based re-theming step is needed the way `chart.ts`
76
78
  * needs one for its canvas.
77
79
  *
80
+ * By default (`layout="fit"`) the plot always squeezes to the measured host
81
+ * width. Three independent, opt-in escape hatches for dense/aligned data:
82
+ * `layout="scroll"` (+ `barWidth`) gives every bar a fixed pixel width and
83
+ * lets the plot overflow the host horizontally (scrollable) instead of
84
+ * squeezing; `maxLabels` decimates which x-axis text labels render (bars
85
+ * always still render) once there are more categories than that; and
86
+ * `barX` lets a consumer hand in its own per-category x-coordinate function
87
+ * — e.g. to pixel-align this chart's bars with a sibling `lyra-heatmap`'s
88
+ * calendar columns — overriding the internal slot math for both bars and
89
+ * their labels. All three are additive and no-ops when left unset.
90
+ *
91
+ * Seven further additive, opt-in properties: `pointText` overrides the
92
+ * per-bar/per-point `<title>`/`aria-label` tooltip text (mirrors
93
+ * `lyra-heatmap`'s `cellText` hook), falling back to the built-in raw-value
94
+ * template when unset; `roundedBars` draws bars as a rounded-top path
95
+ * instead of a square-cornered rect; `skipZero` omits a bar entirely (not
96
+ * just zero-height) for an exactly-`0` value; `padLeft`/`barGapRatio`
97
+ * override the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants; `scale`
98
+ * (`type="bar"` only) switches the bar-height mapping from the default
99
+ * linear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`
100
+ * compression (mirroring `lyra-heatmap`'s matrix-mode `sqrt` scale) so a
101
+ * skewed dataset's smaller bars don't get washed out by one dominant value
102
+ * — gridlines/tick labels stay on the linear domain regardless, only the bar
103
+ * marks' own height changes, and `type="line"` ignores `scale` entirely; and
104
+ * `hideAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether
105
+ * (x-axis category labels, rendered separately, are unaffected).
106
+ *
78
107
  * @customElement lyra-lite-chart
79
108
  * @event lyra-point-click - Fired when a bar/point is activated (click, or
80
109
  * Enter/Space while focused). `detail: { datasetIndex: number, index:
@@ -90,6 +119,8 @@ function niceDomain(dataLo, dataHi, beginAtZero, count) {
90
119
  * @csspart legend - The legend row, when `legend` is set.
91
120
  * @csspart legend-item - Each legend entry.
92
121
  * @csspart legend-swatch - Each legend entry's color swatch.
122
+ * @csspart live-region - The current mark announcement for keyboard users.
123
+ * @csspart data-list - A visually hidden list of all plotted data points.
93
124
  */
94
125
  export class LyraLiteChart extends LyraElement {
95
126
  constructor() {
@@ -104,12 +135,40 @@ export class LyraLiteChart extends LyraElement {
104
135
  this.beginAtZero = true;
105
136
  /** Stacks each category's bars into one segmented bar. Ignored for `type="line"`. */
106
137
  this.stacked = false;
138
+ /** `'fit'` (default) squeezes the plot into the measured host width, unchanged from before this
139
+ * property existed. `'scroll'` gives every bar a fixed `barWidth` instead, letting the plot's
140
+ * content width exceed the host's — the host becomes horizontally scrollable
141
+ * (`overflow-x: auto`) so every bar stays exactly `barWidth` wide regardless of category count.
142
+ * Reflects to the `layout` attribute (e.g. for `:host([layout='scroll'])` host styling). */
143
+ this.layout = 'fit';
144
+ /** Fixed per-category bar width in px, used only when `layout="scroll"`. Ignored (as before this
145
+ * property existed) in `layout="fit"`, the default. */
146
+ this.barWidth = 32;
147
+ /** `type="bar"` only: draws each bar as a rounded-top-corner shape instead of the default
148
+ * square-cornered rect. Default `false` renders exactly today's plain `<rect>`. */
149
+ this.roundedBars = false;
150
+ /** `type="bar"` only: omits a bar entirely (no mark, no `tabindex`, no tooltip) for a value that
151
+ * is exactly `0` — `null`/non-finite values are always skipped regardless of this flag. Default
152
+ * `false` preserves today's behavior of a zero-height but focusable/titled bar. */
153
+ this.skipZero = false;
154
+ /** `type="bar"` only (no effect on `type="line"`): `'linear'` (default) maps a bar's value to
155
+ * height via the standard `niceDomain`-based fraction, unchanged from before this property
156
+ * existed. `'sqrt'` instead maps via `Math.sqrt(value / domainMax)` (mirroring `lyra-heatmap`'s
157
+ * matrix-mode `sqrt` scale), boosting smaller values relative to one dominant value so a skewed
158
+ * dataset's smaller bars don't get washed out. Gridlines/tick labels stay on the linear domain
159
+ * either way — only the bar marks' own height mapping changes. */
160
+ this.scale = 'linear';
161
+ /** Suppresses `renderGrid()` entirely — no gridlines, no y-axis tick labels. x-axis category
162
+ * labels (rendered separately) are unaffected. Default `false` preserves today's behavior. */
163
+ this.hideAxis = false;
107
164
  this.plotWidth = 0;
108
165
  this.plotHeight = 0;
109
166
  this.visible = true;
110
- this.lastSignature = '';
167
+ /** One roving tab stop across all bar/point marks. */
168
+ this.activeMarkIndex = 0;
169
+ this.liveText = '';
111
170
  }
112
- static { this.styles = [LyraElement.styles, styles]; }
171
+ static { this.styles = [LyraElement.styles, styles, srOnly]; }
113
172
  connectedCallback() {
114
173
  super.connectedCallback();
115
174
  this.resizeObserver = new ResizeObserver((entries) => {
@@ -132,12 +191,30 @@ export class LyraLiteChart extends LyraElement {
132
191
  });
133
192
  this.intersectionObserver.observe(this);
134
193
  }
194
+ // A reconnect re-creates the observer above but the `<svg>` render root
195
+ // content survives across disconnect/reconnect (Lit doesn't tear down the
196
+ // shadow root) — re-observe it here (firstUpdated() only ever runs once,
197
+ // on the very first render, so it can't be relied on for a reconnect).
198
+ if (this.svgEl)
199
+ this.resizeObserver.observe(this.svgEl);
135
200
  }
136
201
  disconnectedCallback() {
137
202
  super.disconnectedCallback();
138
203
  this.resizeObserver?.disconnect();
139
204
  this.intersectionObserver?.disconnect();
140
205
  }
206
+ // Kept (not deleted, despite the "delete it" alternative the fix brief
207
+ // offered): connectedCallback() fires *before* Lit's first render, so on
208
+ // the very first mount `this.svgEl` (a `@query('svg')`) is still
209
+ // undefined there and its guarded `observe()` call is a no-op — verified
210
+ // empirically: deleting firstUpdated() here hung every existing test that
211
+ // waits for the ResizeObserver's initial measurement. firstUpdated() runs
212
+ // once, after that first render, and is what actually arms the observer
213
+ // for the initial mount; connectedCallback()'s own observe() call (added
214
+ // above) only ever succeeds on a *reconnect*, when the shadow DOM (and
215
+ // svgEl) already exists from before the disconnect. Together the two
216
+ // cover first-mount and reconnect without ever double-observing the same
217
+ // element from the same callback path.
141
218
  firstUpdated() {
142
219
  if (this.svgEl)
143
220
  this.resizeObserver?.observe(this.svgEl);
@@ -150,6 +227,102 @@ export class LyraLiteChart extends LyraElement {
150
227
  colorFor(index, series) {
151
228
  return series.color ?? DEFAULT_PALETTE[index % DEFAULT_PALETTE.length];
152
229
  }
230
+ /** Dispatches to the host-provided `pointText` formatter when set, otherwise `undefined` (the
231
+ * caller falls back to its own built-in template) — mirrors `lyra-heatmap`'s `resolveCellText()`. */
232
+ resolvePointText(label, value, datasetIndex) {
233
+ return this.pointText?.(label, value, datasetIndex);
234
+ }
235
+ /** The ordered set of visible marks used by both keyboard navigation and
236
+ * the screen-reader data alternative. */
237
+ interactiveMarks() {
238
+ const marks = [];
239
+ if (this.type === 'bar') {
240
+ for (let index = 0; index < this.labels.length; index++) {
241
+ for (let datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
242
+ const value = this.datasets[datasetIndex]?.data[index];
243
+ if (value == null || !Number.isFinite(value) || (this.skipZero && value === 0))
244
+ continue;
245
+ marks.push({ datasetIndex, index, label: this.labels[index] ?? '', value });
246
+ }
247
+ }
248
+ }
249
+ else {
250
+ this.datasets.forEach((series, datasetIndex) => {
251
+ series.data.forEach((value, index) => {
252
+ if (value == null || !Number.isFinite(value))
253
+ return;
254
+ marks.push({ datasetIndex, index, label: this.labels[index] ?? '', value });
255
+ });
256
+ });
257
+ }
258
+ return marks;
259
+ }
260
+ markIndexMap() {
261
+ return new Map(this.interactiveMarks().map((mark, index) => [`${mark.datasetIndex}:${mark.index}`, index]));
262
+ }
263
+ normalizedMarkIndex(marks = this.interactiveMarks()) {
264
+ return marks.length ? Math.min(Math.max(this.activeMarkIndex, 0), marks.length - 1) : -1;
265
+ }
266
+ markAnnouncement(index, marks = this.interactiveMarks()) {
267
+ const mark = marks[index];
268
+ if (!mark)
269
+ return '';
270
+ const series = this.datasets[mark.datasetIndex]?.label ?? 'Series';
271
+ const custom = this.resolvePointText(mark.label, mark.value, mark.datasetIndex);
272
+ return `${custom ?? `${series}, ${mark.label}: ${mark.value}`} (${index + 1} of ${marks.length})`;
273
+ }
274
+ onMarkFocus(index) {
275
+ const marks = this.interactiveMarks();
276
+ if (!marks[index])
277
+ return;
278
+ this.activeMarkIndex = index;
279
+ this.liveText = this.markAnnouncement(index, marks);
280
+ }
281
+ focusMark(index) {
282
+ const marks = this.interactiveMarks();
283
+ if (!marks[index])
284
+ return;
285
+ this.activeMarkIndex = index;
286
+ this.liveText = this.markAnnouncement(index, marks);
287
+ void this.updateComplete.then(() => {
288
+ const markEls = Array.from(this.renderRoot.querySelectorAll('[part="bar"], [part="point"]'));
289
+ markEls[index]?.focus();
290
+ });
291
+ }
292
+ /**
293
+ * A value-to-y-pixel mapping for a bar's top/bottom edge. `'linear'` (the
294
+ * default) is the standard `niceDomain`-fraction formula, unchanged from
295
+ * before `scale` existed. `'sqrt'` instead compresses via
296
+ * `Math.sqrt(value / domainMax)` (mirroring `lyra-heatmap`'s matrix-mode
297
+ * `sqrt` branch), clamping `value` to `[0, hi]` first since a negative
298
+ * input has no real square root — bar charts using `scale="sqrt"` are
299
+ * expected to carry non-negative data, same assumption as the heatmap
300
+ * precedent this mirrors.
301
+ */
302
+ barValueToY(value, plotY, plotH, lo, hi) {
303
+ if (this.scale === 'sqrt') {
304
+ const domainMax = hi > 0 ? hi : 1;
305
+ const frac = Math.sqrt(Math.min(domainMax, Math.max(0, value)) / domainMax);
306
+ return plotY + plotH - frac * plotH;
307
+ }
308
+ const span = hi - lo || 1;
309
+ return plotY + plotH - ((value - lo) / span) * plotH;
310
+ }
311
+ /**
312
+ * A rounded-top-corners `<path>` `d` string for a bar occupying
313
+ * `[x, y, x+w, y+h]` — an SVG `<rect>` can only express a uniform radius
314
+ * on all four corners, so `roundedBars` switches the mark to a path
315
+ * instead of adding `rx`/`ry` to keep the bottom edge square against the
316
+ * baseline. `r` is clamped so it never exceeds half the bar's width or its
317
+ * full height (a thin/short bar degrades to a plain rectangle path rather
318
+ * than self-intersecting).
319
+ */
320
+ roundedBarPath(x, y, w, h) {
321
+ const r = Math.max(0, Math.min(BAR_CORNER_RADIUS, w / 2, h));
322
+ if (r <= 0)
323
+ return `M${x},${y} h${w} v${h} h${-w} Z`;
324
+ return `M${x},${y + r} Q${x},${y} ${x + r},${y} H${x + w - r} Q${x + w},${y} ${x + w},${y + r} V${y + h} H${x} Z`;
325
+ }
153
326
  domain() {
154
327
  let lo = Infinity;
155
328
  let hi = -Infinity;
@@ -188,30 +361,34 @@ export class LyraLiteChart extends LyraElement {
188
361
  }
189
362
  return niceDomain(lo, hi, this.beginAtZero, TICK_COUNT);
190
363
  }
191
- computeSignature() {
192
- return JSON.stringify([
193
- this.type,
194
- this.labels,
195
- this.datasets,
196
- this.legend,
197
- this.xLabel,
198
- this.yLabel,
199
- this.beginAtZero,
200
- this.stacked,
201
- this.plotWidth,
202
- this.plotHeight,
203
- ]);
204
- }
205
364
  emitPoint(datasetIndex, index) {
206
365
  const label = this.labels[index];
207
366
  const value = this.datasets[datasetIndex]?.data[index] ?? null;
208
367
  this.emit('lyra-point-click', { datasetIndex, index, label, value });
209
368
  }
210
- onPointKeyDown(e, datasetIndex, index) {
211
- if (e.key !== 'Enter' && e.key !== ' ')
369
+ onPointKeyDown(e, datasetIndex, index, markIndex) {
370
+ if (e.key === 'Enter' || e.key === ' ') {
371
+ e.preventDefault();
372
+ this.onMarkFocus(markIndex);
373
+ this.emitPoint(datasetIndex, index);
374
+ return;
375
+ }
376
+ const marks = this.interactiveMarks();
377
+ if (!marks.length)
378
+ return;
379
+ let next = markIndex;
380
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown')
381
+ next = Math.min(marks.length - 1, markIndex + 1);
382
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp')
383
+ next = Math.max(0, markIndex - 1);
384
+ else if (e.key === 'Home')
385
+ next = 0;
386
+ else if (e.key === 'End')
387
+ next = marks.length - 1;
388
+ else
212
389
  return;
213
390
  e.preventDefault();
214
- this.emitPoint(datasetIndex, index);
391
+ this.focusMark(next);
215
392
  }
216
393
  renderGrid(plotX, plotY, plotW, plotH, ticks, lo, hi) {
217
394
  const span = hi - lo || 1;
@@ -223,28 +400,43 @@ export class LyraLiteChart extends LyraElement {
223
400
  `;
224
401
  });
225
402
  }
226
- renderBars(plotX, plotY, plotW, plotH, lo, hi) {
227
- const span = hi - lo || 1;
403
+ /**
404
+ * `slot` is the per-category width to lay bars out against — either the
405
+ * measured-width-derived `plotW / n` (`layout="fit"`) or the fixed
406
+ * `barWidth` (`layout="scroll"`), computed once by the caller
407
+ * (`renderChart()`) and handed to both this method and the category-label
408
+ * x-position calc so the two can never drift apart from each other.
409
+ */
410
+ renderBars(plotX, plotY, plotH, slot, lo, hi) {
228
411
  const n = this.labels.length;
229
- const slot = n > 0 ? plotW / n : 0;
230
412
  const groupCount = this.stacked ? 1 : Math.max(1, this.datasets.length);
231
- const groupW = slot * (1 - BAR_GROUP_GAP);
413
+ const groupGap = this.barGapRatio ?? BAR_GROUP_GAP;
414
+ const groupW = slot * (1 - groupGap);
232
415
  const barW = (groupW - BAR_GAP * slot * (groupCount - 1)) / groupCount;
416
+ const markIndexes = this.markIndexMap();
417
+ const activeMarkIndex = this.normalizedMarkIndex();
233
418
  const bars = [];
234
419
  for (let i = 0; i < n; i++) {
235
- const slotStart = plotX + i * slot + (slot - groupW) / 2;
420
+ // `this.barX`, when set, overrides just the category's own x-origin
421
+ // (what an unset `barX` would compute as `plotX + i * slot`) -- the
422
+ // group-centering/per-dataset-offset math below still layers on top of
423
+ // it, same as it does on top of the internal formula.
424
+ const origin = this.barX ? this.barX(i) : plotX + i * slot;
425
+ const slotStart = origin + (slot - groupW) / 2;
236
426
  let stackPos = 0; // running positive-side offset (in value units) for stacked bars
237
427
  let stackNeg = 0; // running negative-side offset
238
428
  this.datasets.forEach((s, di) => {
239
429
  const v = s.data[i];
240
- if (v == null)
430
+ if (v == null || !Number.isFinite(v))
431
+ return;
432
+ if (this.skipZero && v === 0)
241
433
  return;
242
434
  const color = this.colorFor(di, s);
243
- let barX;
435
+ let rectX;
244
436
  let barValLo;
245
437
  let barValHi;
246
438
  if (this.stacked) {
247
- barX = slotStart;
439
+ rectX = slotStart;
248
440
  if (v >= 0) {
249
441
  barValLo = stackPos;
250
442
  barValHi = stackPos + v;
@@ -257,27 +449,49 @@ export class LyraLiteChart extends LyraElement {
257
449
  }
258
450
  }
259
451
  else {
260
- barX = slotStart + di * (barW + BAR_GAP * slot);
261
- barValLo = Math.min(0, v);
262
- barValHi = Math.max(0, v);
452
+ rectX = slotStart + di * (barW + BAR_GAP * slot);
453
+ const zeroClamped = Math.min(hi, Math.max(lo, 0));
454
+ barValLo = Math.min(zeroClamped, v);
455
+ barValHi = Math.max(zeroClamped, v);
263
456
  }
264
- const y1 = plotY + plotH - ((barValHi - lo) / span) * plotH;
265
- const y2 = plotY + plotH - ((barValLo - lo) / span) * plotH;
457
+ const y1 = this.barValueToY(barValHi, plotY, plotH, lo, hi);
458
+ const y2 = this.barValueToY(barValLo, plotY, plotH, lo, hi);
266
459
  const label = this.labels[i];
267
- bars.push(svg `
460
+ const custom = this.resolvePointText(label, v, di);
461
+ const ariaLabel = custom ?? `${s.label}, ${label}: ${v}`;
462
+ const titleText = custom ?? `${s.label} — ${label}: ${v}`;
463
+ const w = Math.max(0, barW);
464
+ const h = Math.max(0, y2 - y1);
465
+ const markIndex = markIndexes.get(`${di}:${i}`);
466
+ bars.push(this.roundedBars
467
+ ? svg `
468
+ <path
469
+ part="bar"
470
+ d=${this.roundedBarPath(rectX, y1, w, h)}
471
+ fill=${color}
472
+ tabindex=${activeMarkIndex === markIndex ? '0' : '-1'}
473
+ role="button"
474
+ aria-label=${ariaLabel}
475
+ @click=${() => this.emitPoint(di, i)}
476
+ @focus=${() => this.onMarkFocus(markIndex)}
477
+ @keydown=${(e) => this.onPointKeyDown(e, di, i, markIndex)}
478
+ ><title>${titleText}</title></path>
479
+ `
480
+ : svg `
268
481
  <rect
269
482
  part="bar"
270
- x=${barX}
483
+ x=${rectX}
271
484
  y=${y1}
272
- width=${Math.max(0, barW)}
273
- height=${Math.max(0, y2 - y1)}
485
+ width=${w}
486
+ height=${h}
274
487
  fill=${color}
275
- tabindex="0"
488
+ tabindex=${activeMarkIndex === markIndex ? '0' : '-1'}
276
489
  role="button"
277
- aria-label=${`${s.label}, ${label}: ${v}`}
490
+ aria-label=${ariaLabel}
278
491
  @click=${() => this.emitPoint(di, i)}
279
- @keydown=${(e) => this.onPointKeyDown(e, di, i)}
280
- ><title>${s.label} ${label}: ${v}</title></rect>
492
+ @focus=${() => this.onMarkFocus(markIndex)}
493
+ @keydown=${(e) => this.onPointKeyDown(e, di, i, markIndex)}
494
+ ><title>${titleText}</title></rect>
281
495
  `);
282
496
  });
283
497
  }
@@ -288,16 +502,29 @@ export class LyraLiteChart extends LyraElement {
288
502
  const n = this.labels.length;
289
503
  const xFor = (i) => plotX + (n > 1 ? (i / (n - 1)) * plotW : plotW / 2);
290
504
  const yFor = (v) => plotY + plotH - ((v - lo) / span) * plotH;
505
+ const markIndexes = this.markIndexMap();
506
+ const activeMarkIndex = this.normalizedMarkIndex();
291
507
  return this.datasets.map((s, di) => {
292
508
  const color = this.colorFor(di, s);
293
- const pts = s.data
294
- .map((v, i) => (v == null ? null : [xFor(i), yFor(v)]))
295
- .filter((p) => p !== null);
296
- const d = pts.map(([x, y], i) => `${i ? 'L' : 'M'}${x},${y}`).join(' ');
509
+ let d = '';
510
+ let penDown = false;
511
+ s.data.forEach((v, i) => {
512
+ if (v == null || !Number.isFinite(v)) {
513
+ penDown = false;
514
+ return;
515
+ }
516
+ const cmd = penDown ? 'L' : 'M';
517
+ d += `${cmd}${xFor(i)},${yFor(v)} `;
518
+ penDown = true;
519
+ });
297
520
  const dots = s.data.map((v, i) => {
298
- if (v == null)
521
+ if (v == null || !Number.isFinite(v))
299
522
  return nothing;
300
523
  const label = this.labels[i];
524
+ const custom = this.resolvePointText(label, v, di);
525
+ const ariaLabel = custom ?? `${s.label}, ${label}: ${v}`;
526
+ const titleText = custom ?? `${s.label} — ${label}: ${v}`;
527
+ const markIndex = markIndexes.get(`${di}:${i}`);
301
528
  return svg `
302
529
  <circle
303
530
  part="point"
@@ -305,51 +532,94 @@ export class LyraLiteChart extends LyraElement {
305
532
  cy=${yFor(v)}
306
533
  r="4"
307
534
  fill=${color}
308
- tabindex="0"
535
+ tabindex=${activeMarkIndex === markIndex ? '0' : '-1'}
309
536
  role="button"
310
- aria-label=${`${s.label}, ${label}: ${v}`}
537
+ aria-label=${ariaLabel}
311
538
  @click=${() => this.emitPoint(di, i)}
312
- @keydown=${(e) => this.onPointKeyDown(e, di, i)}
313
- ><title>${s.label} ${label}: ${v}</title></circle>
539
+ @focus=${() => this.onMarkFocus(markIndex)}
540
+ @keydown=${(e) => this.onPointKeyDown(e, di, i, markIndex)}
541
+ ><title>${titleText}</title></circle>
314
542
  `;
315
543
  });
316
- return svg `<path part="line" d=${d} stroke=${color}></path>${dots}`;
544
+ return svg `<path part="line" d=${d.trim()} stroke=${color}></path>${dots}`;
317
545
  });
318
546
  }
319
547
  render() {
320
- if (!this.visible && this.lastResult)
321
- return this.lastResult;
322
- const signature = this.computeSignature();
323
- if (signature === this.lastSignature && this.lastResult)
324
- return this.lastResult;
325
- this.lastSignature = signature;
326
- const result = this.renderChart();
327
- this.lastResult = result;
328
- return result;
548
+ // Lit already tracks every reactive input, including function-valued
549
+ // properties such as `tickFormat` and `barX`. Returning a cached
550
+ // TemplateResult here would make callback replacement invisible and
551
+ // serializing arbitrary data would throw for circular objects/BigInt.
552
+ // Rendering this small SVG template is cheaper and more correct than a
553
+ // lossy content fingerprint.
554
+ return this.renderChart();
555
+ }
556
+ /**
557
+ * Step size for `maxLabels` decimation: 1 (show every label, today's
558
+ * unchanged default) when `maxLabels` is unset or already >= the label
559
+ * count, otherwise the ceil-divide spacing that lands close to
560
+ * `maxLabels` shown labels while always keeping index 0 and the last
561
+ * index (enforced by the caller, not here).
562
+ */
563
+ labelStep(n) {
564
+ const max = this.maxLabels;
565
+ if (max == null || n <= max)
566
+ return 1;
567
+ return Math.max(1, Math.ceil((n - 1) / Math.max(1, max - 1)));
329
568
  }
330
569
  renderChart() {
331
- const w = this.plotWidth || 400;
570
+ const n = this.labels.length;
332
571
  const h = this.plotHeight || 200;
333
- const padLeft = PAD_LEFT + (this.yLabel ? AXIS_TITLE_SPACE : 0);
572
+ const padLeft = (this.padLeft ?? PAD_LEFT) + (this.yLabel ? AXIS_TITLE_SPACE : 0);
334
573
  const padBottom = PAD_BOTTOM + (this.xLabel ? AXIS_TITLE_SPACE : 0);
335
574
  const plotX = padLeft;
336
575
  const plotY = PAD_TOP;
337
- const plotW = Math.max(0, w - padLeft - PAD_RIGHT);
338
576
  const plotH = Math.max(0, h - plotY - padBottom);
577
+ let w;
578
+ let plotW;
579
+ let slot;
580
+ if (this.layout === 'scroll') {
581
+ // Fixed-width bars: content width is driven by category count ×
582
+ // barWidth instead of the measured host width, and CAN exceed it --
583
+ // the svg gets an explicit inline-size below (not 100%) and
584
+ // `:host([layout='scroll']) [part='base']` (lite-chart.styles.ts)
585
+ // turns on `overflow-x: auto` so the host scrolls to reveal the rest.
586
+ slot = this.barWidth;
587
+ plotW = Math.max(0, n * slot);
588
+ w = plotX + plotW + PAD_RIGHT;
589
+ }
590
+ else {
591
+ // 'fit' (default): squeeze to the measured host width, byte-for-byte
592
+ // the same computation as before `layout` existed.
593
+ w = this.plotWidth || 400;
594
+ plotW = Math.max(0, w - plotX - PAD_RIGHT);
595
+ slot = n > 0 ? plotW / n : 0;
596
+ }
339
597
  const { lo, hi, ticks } = this.domain();
340
- const grid = this.renderGrid(plotX, plotY, plotW, plotH, ticks, lo, hi);
598
+ const grid = this.hideAxis ? [] : this.renderGrid(plotX, plotY, plotW, plotH, ticks, lo, hi);
341
599
  const marks = this.type === 'bar'
342
- ? this.renderBars(plotX, plotY, plotW, plotH, lo, hi)
600
+ ? this.renderBars(plotX, plotY, plotH, slot, lo, hi)
343
601
  : this.renderLines(plotX, plotY, plotW, plotH, lo, hi);
602
+ const step = this.labelStep(n);
344
603
  const categoryLabels = this.labels.map((label, i) => {
345
- const n = this.labels.length;
346
- const x = plotX + (n > 1 ? (i / (n - 1)) * plotW : plotW / 2);
604
+ if (i !== 0 && i !== n - 1 && i % step !== 0)
605
+ return nothing; // maxLabels decimation
606
+ const x = this.type === 'bar' && n > 0
607
+ ? (this.barX ? this.barX(i) : plotX + i * slot) + slot / 2 // matches renderBars()'s own per-category slot center (or the barX override, when set)
608
+ : plotX + (n > 1 ? (i / (n - 1)) * plotW : plotW / 2);
347
609
  return svg `<text part="axis-label" x=${x} y=${plotY + plotH + 14} text-anchor="middle">${label}</text>`;
348
610
  });
349
611
  const chartLabel = this.datasets.map((d) => d.label).join(', ') || 'Chart';
612
+ const marksForA11y = this.interactiveMarks();
613
+ const activeMark = this.normalizedMarkIndex(marksForA11y);
350
614
  return html `
351
615
  <div part="base">
352
- <svg viewBox="0 0 ${w} ${h}" role="group" aria-label=${chartLabel}>
616
+ <svg
617
+ viewBox="0 0 ${w} ${h}"
618
+ style=${this.layout === 'scroll' ? `inline-size: ${w}px` : nothing}
619
+ role="group"
620
+ aria-label=${chartLabel}
621
+ tabindex=${marksForA11y.length ? '-1' : '0'}
622
+ >
353
623
  ${grid}
354
624
  ${categoryLabels}
355
625
  ${marks}
@@ -360,6 +630,12 @@ export class LyraLiteChart extends LyraElement {
360
630
  ? svg `<text part="axis-title" x=${plotX + plotW / 2} y=${plotY + plotH + padBottom - 2} text-anchor="middle">${this.xLabel}</text>`
361
631
  : nothing}
362
632
  </svg>
633
+ <div part="live-region" class="sr-only" role="status" aria-live="polite" aria-atomic="true">
634
+ ${activeMark >= 0 ? this.liveText || this.markAnnouncement(activeMark, marksForA11y) : ''}
635
+ </div>
636
+ <ul part="data-list" class="sr-only" aria-label="Chart data">
637
+ ${marksForA11y.map((mark, index) => html `<li>${this.markAnnouncement(index, marksForA11y)}</li>`)}
638
+ </ul>
363
639
  ${this.legend
364
640
  ? html `<div part="legend">
365
641
  ${this.datasets.map((s, i) => html `
@@ -404,6 +680,39 @@ __decorate([
404
680
  __decorate([
405
681
  property({ attribute: false })
406
682
  ], LyraLiteChart.prototype, "tickFormat", void 0);
683
+ __decorate([
684
+ property({ reflect: true })
685
+ ], LyraLiteChart.prototype, "layout", void 0);
686
+ __decorate([
687
+ property({ type: Number, attribute: 'bar-width' })
688
+ ], LyraLiteChart.prototype, "barWidth", void 0);
689
+ __decorate([
690
+ property({ type: Number, attribute: 'max-labels' })
691
+ ], LyraLiteChart.prototype, "maxLabels", void 0);
692
+ __decorate([
693
+ property({ attribute: false })
694
+ ], LyraLiteChart.prototype, "barX", void 0);
695
+ __decorate([
696
+ property({ attribute: false })
697
+ ], LyraLiteChart.prototype, "pointText", void 0);
698
+ __decorate([
699
+ property({ type: Boolean, attribute: 'rounded-bars' })
700
+ ], LyraLiteChart.prototype, "roundedBars", void 0);
701
+ __decorate([
702
+ property({ type: Boolean, attribute: 'skip-zero' })
703
+ ], LyraLiteChart.prototype, "skipZero", void 0);
704
+ __decorate([
705
+ property({ type: Number, attribute: 'pad-left' })
706
+ ], LyraLiteChart.prototype, "padLeft", void 0);
707
+ __decorate([
708
+ property({ type: Number, attribute: 'bar-gap-ratio' })
709
+ ], LyraLiteChart.prototype, "barGapRatio", void 0);
710
+ __decorate([
711
+ property()
712
+ ], LyraLiteChart.prototype, "scale", void 0);
713
+ __decorate([
714
+ property({ type: Boolean, attribute: 'hide-axis' })
715
+ ], LyraLiteChart.prototype, "hideAxis", void 0);
407
716
  __decorate([
408
717
  state()
409
718
  ], LyraLiteChart.prototype, "plotWidth", void 0);
@@ -413,6 +722,12 @@ __decorate([
413
722
  __decorate([
414
723
  state()
415
724
  ], LyraLiteChart.prototype, "visible", void 0);
725
+ __decorate([
726
+ state()
727
+ ], LyraLiteChart.prototype, "activeMarkIndex", void 0);
728
+ __decorate([
729
+ state()
730
+ ], LyraLiteChart.prototype, "liveText", void 0);
416
731
  __decorate([
417
732
  query('svg')
418
733
  ], LyraLiteChart.prototype, "svgEl", void 0);
@@ -23,6 +23,15 @@ export const styles = css `
23
23
  flex-direction: column;
24
24
  gap: var(--lyra-space-xs);
25
25
  }
26
+ /* layout="scroll": the svg below gets an explicit inline-size (its
27
+ computed content width, set inline per-render since it depends on
28
+ category count/barWidth) instead of the 100% below, and can end up
29
+ wider than this container -- scroll to reveal the rest instead of
30
+ squeezing. Scoped strictly to the reflected [layout='scroll'] attribute
31
+ so layout="fit" (the default) never triggers this rule. */
32
+ :host([layout='scroll']) [part='base'] {
33
+ overflow-x: auto;
34
+ }
26
35
  svg {
27
36
  flex: 1 1 auto;
28
37
  inline-size: 100%;
@@ -1,4 +1,4 @@
1
- import { LyraChart } from './chart.js';
1
+ import { LyraChart, lockChartType } from './chart.js';
2
2
  import { defineElement } from '../../internal/prefix.js';
3
3
  /**
4
4
  * `<lyra-pie-chart>` — `<lyra-chart>` with `type` locked to `"pie"`. Single-series:
@@ -8,21 +8,5 @@ import { defineElement } from '../../internal/prefix.js';
8
8
  */
9
9
  export class LyraPieChart extends LyraChart {
10
10
  }
11
- // `type` is locked read-only rather than a settable class field with just a
12
- // default value — `LyraChart` declares it as a plain (decorator-managed)
13
- // class field, and TypeScript forbids a subclass from re-declaring a base
14
- // field as a getter/setter pair via ordinary class syntax (TS2611) — so the
15
- // accessor pair is installed directly on the prototype instead, which is
16
- // runtime-equivalent (same shadowing semantics as a class-syntax override)
17
- // without tripping that check.
18
- Object.defineProperty(LyraPieChart.prototype, 'type', {
19
- configurable: true,
20
- enumerable: true,
21
- get() {
22
- return 'pie';
23
- },
24
- set(_v) {
25
- /* locked to 'pie'; direct writes are ignored */
26
- },
27
- });
11
+ lockChartType(LyraPieChart, 'pie');
28
12
  defineElement('pie-chart', LyraPieChart);