@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
@@ -4,6 +4,7 @@ import '../skeleton/skeleton.js';
4
4
  export interface GraphNode {
5
5
  id: string;
6
6
  label?: string;
7
+ /** Clamped to [6, 24] (a non-finite/missing value uses the midpoint, 15) — never rendered smaller/larger. */
7
8
  radius?: number;
8
9
  color?: string;
9
10
  }
@@ -19,12 +20,24 @@ export interface GraphLink {
19
20
  *
20
21
  * Set `seed` for a deterministic layout: node initial positions become
21
22
  * reproducible (keyed by node id) and the settle happens synchronously
22
- * instead of animating, like `prefers-reduced-motion`.
23
+ * instead of animating, like `prefers-reduced-motion`. `seed` only takes
24
+ * effect on the update that first populates `nodes`/`links` (or a later
25
+ * update that adds genuinely new node ids) — willUpdate() only reads it from
26
+ * inside rebuildSimulation(), which itself only ever assigns x/y to nodes
27
+ * that don't already have a settled position, so changing `seed` on an
28
+ * already-rendered graph is a no-op; nothing re-derives already-positioned
29
+ * nodes' x/y from the new value.
23
30
  *
24
31
  * @customElement lyra-graph
25
32
  * @event lyra-node-click - `detail: { id }`.
26
33
  * @event lyra-link-click - `detail: { source, target }`.
27
- * @csspart base, svg, node, link, label
34
+ * @csspart base - The graph wrapper.
35
+ * @csspart svg - The graph SVG.
36
+ * @csspart node - A graph node.
37
+ * @csspart link - A graph link.
38
+ * @csspart label - A node label.
39
+ * @csspart live-region - The current graph item announcement.
40
+ * @csspart data-list - A visually hidden list alternative for graph data.
28
41
  */
29
42
  export declare class LyraGraph extends LyraElement {
30
43
  static styles: import("lit").CSSResultGroup[];
@@ -38,12 +51,20 @@ export declare class LyraGraph extends LyraElement {
38
51
  maxZoom: number;
39
52
  /** When set, seeds each node's initial x/y deterministically (keyed by
40
53
  * node id, not array index) instead of forceSimulation()'s own random
41
- * start, and settles the simulation synchronously — see rebuildSimulation(). */
54
+ * start, and settles the simulation synchronously — see rebuildSimulation().
55
+ * Only takes effect on the update that first assigns a given node id an
56
+ * x/y (i.e. supplied at/before `nodes`/`links` first populate, or when a
57
+ * later update introduces new node ids) — changing `seed` afterwards does
58
+ * not retroactively reposition already-settled nodes; there is currently
59
+ * no way to make an already-rendered graph reproducible after the fact. */
42
60
  seed?: number;
43
61
  /** True until the lazy-loaded d3 peer dependencies have settled (success or failure). */
44
62
  private loading;
45
63
  private simNodes;
46
64
  private simLinks;
65
+ /** One roving tab stop across all nodes and links; nodes are the initial entry order. */
66
+ private activeGraphItem;
67
+ private graphLiveText;
47
68
  private simulation?;
48
69
  /** The live charge/link force objects, kept so chargeStrength/linkDistance
49
70
  * changes can retune them in place (see updated()) instead of requiring a
@@ -73,6 +94,13 @@ export declare class LyraGraph extends LyraElement {
73
94
  private linkEls;
74
95
  connectedCallback(): void;
75
96
  disconnectedCallback(): void;
97
+ /**
98
+ * A caller-supplied `radius` is clamped to [MIN_RADIUS, MAX_RADIUS] (and a
99
+ * non-finite/NaN value falls back to the same default average as an unset
100
+ * one) — an unclamped 0/negative radius would render an invisibly small
101
+ * `<circle>` that's still `role="button" tabindex="0"`, an invisible,
102
+ * focusable/clickable control with no visible focus indicator.
103
+ */
76
104
  private nodeRadius;
77
105
  protected willUpdate(changed: PropertyValues): void;
78
106
  protected updated(changed: PropertyValues): void;
@@ -114,6 +142,12 @@ export declare class LyraGraph extends LyraElement {
114
142
  private rebuildSimulation;
115
143
  private onNodeClick;
116
144
  private onLinkClick;
145
+ private graphItemCount;
146
+ private normalizedGraphItem;
147
+ private graphItemText;
148
+ private onGraphItemFocus;
149
+ private focusGraphItem;
150
+ private onGraphKeyDown;
117
151
  render(): TemplateResult;
118
152
  }
119
153
  declare global {
@@ -9,6 +9,7 @@ import { property, state } from 'lit/decorators.js';
9
9
  import { styleMap } from 'lit/directives/style-map.js';
10
10
  import { LyraElement } from '../../internal/lyra-element.js';
11
11
  import { defineElement } from '../../internal/prefix.js';
12
+ import { srOnly } from '../../internal/a11y.js';
12
13
  import { styles } from './graph.styles.js';
13
14
  import { loadD3 } from './graph-loader.js';
14
15
  import '../skeleton/skeleton.js';
@@ -67,12 +68,24 @@ function sanitizeNodeColor(color) {
67
68
  *
68
69
  * Set `seed` for a deterministic layout: node initial positions become
69
70
  * reproducible (keyed by node id) and the settle happens synchronously
70
- * instead of animating, like `prefers-reduced-motion`.
71
+ * instead of animating, like `prefers-reduced-motion`. `seed` only takes
72
+ * effect on the update that first populates `nodes`/`links` (or a later
73
+ * update that adds genuinely new node ids) — willUpdate() only reads it from
74
+ * inside rebuildSimulation(), which itself only ever assigns x/y to nodes
75
+ * that don't already have a settled position, so changing `seed` on an
76
+ * already-rendered graph is a no-op; nothing re-derives already-positioned
77
+ * nodes' x/y from the new value.
71
78
  *
72
79
  * @customElement lyra-graph
73
80
  * @event lyra-node-click - `detail: { id }`.
74
81
  * @event lyra-link-click - `detail: { source, target }`.
75
- * @csspart base, svg, node, link, label
82
+ * @csspart base - The graph wrapper.
83
+ * @csspart svg - The graph SVG.
84
+ * @csspart node - A graph node.
85
+ * @csspart link - A graph link.
86
+ * @csspart label - A node label.
87
+ * @csspart live-region - The current graph item announcement.
88
+ * @csspart data-list - A visually hidden list alternative for graph data.
76
89
  */
77
90
  export class LyraGraph extends LyraElement {
78
91
  constructor() {
@@ -89,6 +102,9 @@ export class LyraGraph extends LyraElement {
89
102
  this.loading = true;
90
103
  this.simNodes = [];
91
104
  this.simLinks = [];
105
+ /** One roving tab stop across all nodes and links; nodes are the initial entry order. */
106
+ this.activeGraphItem = 0;
107
+ this.graphLiveText = '';
92
108
  /** Node `<circle>`s already wired up with d3-drag; cleared on every simulation rebuild
93
109
  * so DOM elements Lit reuses across a rebuild get rebound to their fresh datum. */
94
110
  this.boundNodeEls = new WeakSet();
@@ -100,9 +116,22 @@ export class LyraGraph extends LyraElement {
100
116
  this.nodeLabelEls = [];
101
117
  this.linkEls = [];
102
118
  }
103
- static { this.styles = [LyraElement.styles, styles]; }
119
+ static { this.styles = [LyraElement.styles, styles, srOnly]; }
104
120
  connectedCallback() {
105
121
  super.connectedCallback();
122
+ // A reconnect (e.g. a drag-and-drop reparent that keeps this same
123
+ // element instance) fires disconnectedCallback then connectedCallback
124
+ // synchronously with no update in between — this.d3 is already set from
125
+ // the initial mount, and the live simulation/DOM are still intact
126
+ // (disconnectedCallback only stops the simulation's timer, it doesn't
127
+ // tear anything down). Redoing the lazy-load + rebuildSimulation() here
128
+ // would discard every already-settled node's position and restart the
129
+ // whole ~300-tick alpha=1 settle animation for no reason — just resume
130
+ // the existing simulation in place instead.
131
+ if (this.d3) {
132
+ this.simulation?.restart();
133
+ return;
134
+ }
106
135
  void loadD3().then((mods) => {
107
136
  this.loading = false;
108
137
  // The element may have been removed from the DOM while the dynamic
@@ -118,8 +147,16 @@ export class LyraGraph extends LyraElement {
118
147
  super.disconnectedCallback();
119
148
  this.simulation?.stop();
120
149
  }
150
+ /**
151
+ * A caller-supplied `radius` is clamped to [MIN_RADIUS, MAX_RADIUS] (and a
152
+ * non-finite/NaN value falls back to the same default average as an unset
153
+ * one) — an unclamped 0/negative radius would render an invisibly small
154
+ * `<circle>` that's still `role="button" tabindex="0"`, an invisible,
155
+ * focusable/clickable control with no visible focus indicator.
156
+ */
121
157
  nodeRadius(n) {
122
- return n.radius ?? (MIN_RADIUS + MAX_RADIUS) / 2;
158
+ const r = n.radius ?? (MIN_RADIUS + MAX_RADIUS) / 2;
159
+ return Number.isFinite(r) ? Math.min(MAX_RADIUS, Math.max(MIN_RADIUS, r)) : (MIN_RADIUS + MAX_RADIUS) / 2;
123
160
  }
124
161
  willUpdate(changed) {
125
162
  // rebuildSimulation() (re)assigns the simNodes/simLinks reactive
@@ -355,6 +392,69 @@ export class LyraGraph extends LyraElement {
355
392
  const target = typeof link.target === 'object' ? link.target.id : String(link.target);
356
393
  this.emit('lyra-link-click', { source, target });
357
394
  }
395
+ graphItemCount() {
396
+ return this.simNodes.length + this.simLinks.length;
397
+ }
398
+ normalizedGraphItem(index = this.activeGraphItem) {
399
+ const count = this.graphItemCount();
400
+ return count ? Math.min(Math.max(index, 0), count - 1) : -1;
401
+ }
402
+ graphItemText(index) {
403
+ if (index < this.simNodes.length) {
404
+ const node = this.simNodes[index];
405
+ return node ? `Node ${node.label ?? node.id}` : '';
406
+ }
407
+ const link = this.simLinks[index - this.simNodes.length];
408
+ if (!link)
409
+ return '';
410
+ const source = typeof link.source === 'object' ? link.source.label ?? link.source.id : String(link.source);
411
+ const target = typeof link.target === 'object' ? link.target.label ?? link.target.id : String(link.target);
412
+ return `Link from ${source} to ${target}`;
413
+ }
414
+ onGraphItemFocus(index) {
415
+ if (this.normalizedGraphItem(index) < 0)
416
+ return;
417
+ this.activeGraphItem = index;
418
+ this.graphLiveText = `${this.graphItemText(index)} (${index + 1} of ${this.graphItemCount()})`;
419
+ }
420
+ focusGraphItem(index) {
421
+ const normalized = this.normalizedGraphItem(index);
422
+ if (normalized < 0)
423
+ return;
424
+ this.activeGraphItem = normalized;
425
+ this.graphLiveText = `${this.graphItemText(normalized)} (${normalized + 1} of ${this.graphItemCount()})`;
426
+ void this.updateComplete.then(() => {
427
+ const items = [
428
+ ...Array.from(this.renderRoot.querySelectorAll('[part="node"]')),
429
+ ...Array.from(this.renderRoot.querySelectorAll('[part="link"]')),
430
+ ];
431
+ items[normalized]?.focus();
432
+ });
433
+ }
434
+ onGraphKeyDown(e, index, activate) {
435
+ if (e.key === 'Enter' || e.key === ' ') {
436
+ e.preventDefault();
437
+ this.onGraphItemFocus(index);
438
+ activate();
439
+ return;
440
+ }
441
+ const count = this.graphItemCount();
442
+ if (!count)
443
+ return;
444
+ let next = index;
445
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown')
446
+ next = Math.min(count - 1, index + 1);
447
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp')
448
+ next = Math.max(0, index - 1);
449
+ else if (e.key === 'Home')
450
+ next = 0;
451
+ else if (e.key === 'End')
452
+ next = count - 1;
453
+ else
454
+ return;
455
+ e.preventDefault();
456
+ this.focusGraphItem(next);
457
+ }
358
458
  render() {
359
459
  if (this.loading) {
360
460
  return html `
@@ -373,15 +473,17 @@ export class LyraGraph extends LyraElement {
373
473
  role="group"
374
474
  aria-label="Node-link diagram with ${this.simNodes.length} nodes and ${this.simLinks.length} links"
375
475
  viewBox="0 0 ${this.width} ${this.height}"
476
+ tabindex=${this.graphItemCount() ? '-1' : '0'}
376
477
  >
377
478
  <g transform="">
378
- ${this.simLinks.map((l) => {
479
+ ${this.simLinks.map((l, linkIndex) => {
379
480
  const source = l.source;
380
481
  const target = l.target;
482
+ const itemIndex = this.simNodes.length + linkIndex;
381
483
  return svg `<line
382
484
  part="link"
383
485
  role="button"
384
- tabindex="0"
486
+ tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
385
487
  aria-label="Link from ${source.label ?? source.id} to ${target.label ?? target.id}"
386
488
  stroke-width=${l.width ?? 1.5}
387
489
  x1=${source.x ?? 0}
@@ -389,33 +491,26 @@ export class LyraGraph extends LyraElement {
389
491
  x2=${target.x ?? 0}
390
492
  y2=${target.y ?? 0}
391
493
  @click=${() => this.onLinkClick(l)}
392
- @keydown=${(e) => {
393
- if (e.key === 'Enter' || e.key === ' ') {
394
- e.preventDefault();
395
- this.onLinkClick(l);
396
- }
397
- }}
494
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
495
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onLinkClick(l))}
398
496
  ></line>`;
399
497
  })}
400
- ${this.simNodes.map((n) => {
498
+ ${this.simNodes.map((n, nodeIndex) => {
401
499
  const fill = sanitizeNodeColor(n.color);
500
+ const itemIndex = nodeIndex;
402
501
  return svg `<g>
403
502
  <circle
404
503
  part="node"
405
504
  role="button"
406
- tabindex="0"
505
+ tabindex=${this.normalizedGraphItem() === itemIndex ? '0' : '-1'}
407
506
  aria-label=${n.label ?? n.id}
408
507
  r=${this.nodeRadius(n)}
409
508
  cx=${n.x ?? 0}
410
509
  cy=${n.y ?? 0}
411
510
  style=${styleMap(fill ? { '--lyra-node-fill': fill } : {})}
412
511
  @click=${() => this.onNodeClick(n)}
413
- @keydown=${(e) => {
414
- if (e.key === 'Enter' || e.key === ' ') {
415
- e.preventDefault();
416
- this.onNodeClick(n);
417
- }
418
- }}
512
+ @focus=${() => this.onGraphItemFocus(itemIndex)}
513
+ @keydown=${(e) => this.onGraphKeyDown(e, itemIndex, () => this.onNodeClick(n))}
419
514
  ></circle>
420
515
  ${n.label
421
516
  ? svg `<text part="label" aria-hidden="true" x=${(n.x ?? 0) + this.nodeRadius(n) + 2} y=${n.y ?? 0}>${n.label}</text>`
@@ -424,6 +519,17 @@ export class LyraGraph extends LyraElement {
424
519
  })}
425
520
  </g>
426
521
  </svg>
522
+ <div part="live-region" class="sr-only" role="status" aria-live="polite" aria-atomic="true">
523
+ ${this.graphLiveText || (this.normalizedGraphItem() >= 0 ? `${this.graphItemText(this.normalizedGraphItem())} (1 of ${this.graphItemCount()})` : '')}
524
+ </div>
525
+ <ul part="data-list" class="sr-only" aria-label="Graph data">
526
+ ${this.simNodes.map((node) => html `<li>Node ${node.label ?? node.id}</li>`)}
527
+ ${this.simLinks.map((link) => {
528
+ const source = link.source;
529
+ const target = link.target;
530
+ return html `<li>Link from ${source.label ?? source.id} to ${target.label ?? target.id}</li>`;
531
+ })}
532
+ </ul>
427
533
  </div>
428
534
  `;
429
535
  }
@@ -464,4 +570,10 @@ __decorate([
464
570
  __decorate([
465
571
  state()
466
572
  ], LyraGraph.prototype, "simLinks", void 0);
573
+ __decorate([
574
+ state()
575
+ ], LyraGraph.prototype, "activeGraphItem", void 0);
576
+ __decorate([
577
+ state()
578
+ ], LyraGraph.prototype, "graphLiveText", void 0);
467
579
  defineElement('graph', LyraGraph);
@@ -6,26 +6,38 @@ export interface CalendarDay {
6
6
  export interface CalendarCell {
7
7
  date: string;
8
8
  value: number;
9
- /** 0-based week column, counting from the grid's first (earliest-containing) Sunday. */
9
+ /** 0-based week column, counting from the grid's first (earliest-containing) anchor week — see `buildCalendarGrid()`'s `firstDayOfWeek` parameter. */
10
10
  week: number;
11
- /** 0 (Sunday) .. 6 (Saturday). */
11
+ /**
12
+ * Day-of-week position within the row, relative to `firstDayOfWeek`: 0 for
13
+ * the anchor weekday itself, up to 6 for the day immediately before it.
14
+ * With the default `firstDayOfWeek` of 0, this is the familiar 0 (Sunday)
15
+ * .. 6 (Saturday) numbering, unchanged from before `firstDayOfWeek` existed.
16
+ */
12
17
  weekday: number;
13
18
  }
14
19
  /** Parses a `yyyy-mm-dd` string as UTC midnight, avoiding local-timezone day-boundary drift. */
15
20
  export declare function parseIsoDate(iso: string): Date;
16
21
  /**
17
- * Lays `days` out onto a GitHub-style Sunday-Saturday x week grid. `days`
18
- * need not be sorted or contiguous; the grid spans from the earliest to the
19
- * latest date present, anchored at the Sunday on/before the earliest date.
22
+ * Lays `days` out onto a GitHub-style week grid, 7 rows deep. `days` need not
23
+ * be sorted or contiguous; the grid spans from the earliest to the latest
24
+ * date present, anchored at the `firstDayOfWeek`-weekday on/before the
25
+ * earliest date (`firstDayOfWeek` is 0–6, Sunday-first by default — same
26
+ * numbering as `CalendarCell.weekday`). With the default `firstDayOfWeek` of
27
+ * 0, this is the Sunday on/before the earliest date, exactly as before this
28
+ * parameter existed.
20
29
  *
21
30
  * An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
22
31
  * `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
23
32
  * string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
24
33
  * single `NaN` reach the min/max below would poison `firstWeekStart` (and
25
34
  * therefore every cell's `week`) for the whole grid instead of just the bad
26
- * entry.
35
+ * entry. Likewise, an entry whose `date` is numerically well-formed but
36
+ * calendar-invalid (e.g. `'2026-02-30'`, which `Date.UTC` silently rolls
37
+ * over into March) is dropped rather than silently renormalized — see
38
+ * `isCalendarValid()`.
27
39
  */
28
- export declare function buildCalendarGrid(days: CalendarDay[]): {
40
+ export declare function buildCalendarGrid(days: CalendarDay[], firstDayOfWeek?: number): {
29
41
  cells: CalendarCell[];
30
42
  weekCount: number;
31
43
  firstWeekStart: Date;
@@ -5,47 +5,71 @@ export function parseIsoDate(iso) {
5
5
  const [y, m, d] = iso.split('-').map(Number);
6
6
  return new Date(Date.UTC(y, m - 1, d));
7
7
  }
8
+ /** Whether `iso` (already run through parseIsoDate) actually round-trips —
9
+ * Date.UTC silently rolls e.g. day 30 of a 28-day February into March. */
10
+ function isCalendarValid(iso, parsed) {
11
+ const [y, m, d] = iso.split('-').map(Number);
12
+ return parsed.getUTCFullYear() === y && parsed.getUTCMonth() === m - 1 && parsed.getUTCDate() === d;
13
+ }
8
14
  /**
9
- * Lays `days` out onto a GitHub-style Sunday-Saturday x week grid. `days`
10
- * need not be sorted or contiguous; the grid spans from the earliest to the
11
- * latest date present, anchored at the Sunday on/before the earliest date.
15
+ * Lays `days` out onto a GitHub-style week grid, 7 rows deep. `days` need not
16
+ * be sorted or contiguous; the grid spans from the earliest to the latest
17
+ * date present, anchored at the `firstDayOfWeek`-weekday on/before the
18
+ * earliest date (`firstDayOfWeek` is 0–6, Sunday-first by default — same
19
+ * numbering as `CalendarCell.weekday`). With the default `firstDayOfWeek` of
20
+ * 0, this is the Sunday on/before the earliest date, exactly as before this
21
+ * parameter existed.
12
22
  *
13
23
  * An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
14
24
  * `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
15
25
  * string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
16
26
  * single `NaN` reach the min/max below would poison `firstWeekStart` (and
17
27
  * therefore every cell's `week`) for the whole grid instead of just the bad
18
- * entry.
28
+ * entry. Likewise, an entry whose `date` is numerically well-formed but
29
+ * calendar-invalid (e.g. `'2026-02-30'`, which `Date.UTC` silently rolls
30
+ * over into March) is dropped rather than silently renormalized — see
31
+ * `isCalendarValid()`.
19
32
  */
20
- export function buildCalendarGrid(days) {
33
+ export function buildCalendarGrid(days, firstDayOfWeek = 0) {
21
34
  const parsed = days
22
35
  .map((d) => ({ ...d, dateObj: parseIsoDate(d.date) }))
23
- .filter((d) => !Number.isNaN(d.dateObj.getTime()));
36
+ .filter((d) => !Number.isNaN(d.dateObj.getTime()) && isCalendarValid(d.date, d.dateObj));
24
37
  if (parsed.length === 0) {
25
38
  return { cells: [], weekCount: 0, firstWeekStart: new Date(0), monthLabels: [] };
26
39
  }
27
40
  const timeBounds = minMax(parsed.map((d) => d.dateObj.getTime()));
28
41
  const min = new Date(timeBounds[0]);
29
- const firstWeekStart = new Date(Date.UTC(min.getUTCFullYear(), min.getUTCMonth(), min.getUTCDate() - min.getUTCDay()));
42
+ // Days back from `min` to the nearest `firstDayOfWeek`-weekday on/before
43
+ // it — with the default firstDayOfWeek of 0, this reduces to
44
+ // `min.getUTCDay()` exactly, i.e. today's original Sunday anchor.
45
+ const daysBackToAnchor = (min.getUTCDay() - firstDayOfWeek + 7) % 7;
46
+ const firstWeekStart = new Date(Date.UTC(min.getUTCFullYear(), min.getUTCMonth(), min.getUTCDate() - daysBackToAnchor));
30
47
  const cells = parsed.map((d) => {
31
- const weekday = d.dateObj.getUTCDay();
48
+ // Relative to the anchor weekday (see `CalendarCell.weekday`'s doc
49
+ // comment) — with the default firstDayOfWeek of 0 this is just
50
+ // `d.dateObj.getUTCDay()`, unchanged from before.
51
+ const weekday = (d.dateObj.getUTCDay() - firstDayOfWeek + 7) % 7;
32
52
  const daysSinceStart = Math.round((d.dateObj.getTime() - firstWeekStart.getTime()) / MS_PER_DAY);
33
53
  const week = Math.floor(daysSinceStart / 7);
34
54
  return { date: d.date, value: d.value, week, weekday };
35
55
  });
36
56
  const weekCount = minMax(cells.map((c) => c.week))[1] + 1;
57
+ // Label every distinct (year, month) present in the data, not just months
58
+ // that happen to contain a Sunday-anchored cell — a sparse calendar (few
59
+ // days per month, none landing on a Sunday) would otherwise render zero
60
+ // month labels for months that do have data.
37
61
  const monthLabels = [];
38
- let lastMonth = -1;
39
- for (const cell of cells.slice().sort((a, b) => a.week - b.week)) {
62
+ const seenMonths = new Set();
63
+ for (const cell of cells.slice().sort((a, b) => a.week - b.week || a.weekday - b.weekday)) {
40
64
  const cellDate = parseIsoDate(cell.date);
41
- const month = cellDate.getUTCMonth();
42
- if (cell.weekday === 0 && month !== lastMonth) {
43
- lastMonth = month;
44
- monthLabels.push({
45
- week: cell.week,
46
- label: cellDate.toLocaleString('en', { month: 'short', timeZone: 'UTC' }),
47
- });
48
- }
65
+ const key = `${cellDate.getUTCFullYear()}-${cellDate.getUTCMonth()}`;
66
+ if (seenMonths.has(key))
67
+ continue;
68
+ seenMonths.add(key);
69
+ monthLabels.push({
70
+ week: cell.week,
71
+ label: cellDate.toLocaleString(undefined, { month: 'short', timeZone: 'UTC' }),
72
+ });
49
73
  }
50
74
  return { cells, weekCount, firstWeekStart, monthLabels };
51
75
  }
@@ -1,4 +1,4 @@
1
- /** Maps `value` in `[lo, hi]` to a 0.11.0 alpha, matching the cd-heatmap ramp. */
1
+ /** Maps `value` in `[lo, hi]` to a 0.1-1.0 alpha so the lowest real value still reads as faintly present rather than invisible. */
2
2
  export declare function linearAlpha(value: number, lo: number, hi: number): number;
3
3
  /**
4
4
  * Computes `[min, max]` of `values` via a linear scan, or `null` for an
@@ -12,5 +12,15 @@ export declare function minMax(values: number[]): [number, number] | null;
12
12
  * Square-root-scaled bucket index in `[0, steps-1]`, or `-1` for no-data.
13
13
  * Compresses large counts so a single heavy cell doesn't wash out the rest
14
14
  * of a sequential color ramp.
15
+ *
16
+ * Only a negative `count` means "no data" here — the true no-data sentinel
17
+ * (`v < 0 || !Number.isFinite(v)`) is already filtered out by the caller
18
+ * (`drawMatrix()`) before `sqrtStep` is ever invoked, so a real `count === 0`
19
+ * (e.g. "zero events that day") reaches this function and must bucket to the
20
+ * lowest ramp step like any other legitimate value, not render as no-data.
21
+ * Likewise, `max <= 0` means every real value in the dataset is zero (a
22
+ * legitimate "zero events everywhere" dataset, not an absence of data) — the
23
+ * whole range collapses to a single point, so `count` (itself necessarily 0)
24
+ * buckets to the lowest step rather than being misread as no-data.
15
25
  */
16
26
  export declare function sqrtStep(count: number, max: number, steps: number): number;
@@ -1,4 +1,4 @@
1
- /** Maps `value` in `[lo, hi]` to a 0.11.0 alpha, matching the cd-heatmap ramp. */
1
+ /** Maps `value` in `[lo, hi]` to a 0.1-1.0 alpha so the lowest real value still reads as faintly present rather than invisible. */
2
2
  export function linearAlpha(value, lo, hi) {
3
3
  const span = hi - lo || 1;
4
4
  const t = (value - lo) / span;
@@ -29,10 +29,22 @@ export function minMax(values) {
29
29
  * Square-root-scaled bucket index in `[0, steps-1]`, or `-1` for no-data.
30
30
  * Compresses large counts so a single heavy cell doesn't wash out the rest
31
31
  * of a sequential color ramp.
32
+ *
33
+ * Only a negative `count` means "no data" here — the true no-data sentinel
34
+ * (`v < 0 || !Number.isFinite(v)`) is already filtered out by the caller
35
+ * (`drawMatrix()`) before `sqrtStep` is ever invoked, so a real `count === 0`
36
+ * (e.g. "zero events that day") reaches this function and must bucket to the
37
+ * lowest ramp step like any other legitimate value, not render as no-data.
38
+ * Likewise, `max <= 0` means every real value in the dataset is zero (a
39
+ * legitimate "zero events everywhere" dataset, not an absence of data) — the
40
+ * whole range collapses to a single point, so `count` (itself necessarily 0)
41
+ * buckets to the lowest step rather than being misread as no-data.
32
42
  */
33
43
  export function sqrtStep(count, max, steps) {
34
- if (count <= 0 || max <= 0)
44
+ if (count < 0)
35
45
  return -1;
46
+ if (max <= 0)
47
+ return 0;
36
48
  const ratio = Math.sqrt(count) / Math.sqrt(max);
37
49
  return Math.min(steps - 1, Math.floor(ratio * steps));
38
50
  }