@nocoo/basalt 2.1.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/README.md +2 -0
  2. package/ai/COMPATIBILITY.md +11 -1
  3. package/ai/DESIGN.md +342 -0
  4. package/ai/INTEGRATION.md +239 -152
  5. package/ai/RECIPES.md +96 -26
  6. package/ai/USAGE.md +5 -5
  7. package/ai/registry.json +2883 -275
  8. package/dist/assets/brand-mark.js.map +1 -1
  9. package/dist/charts/area.js.map +1 -1
  10. package/dist/charts/bar.js.map +1 -1
  11. package/dist/charts/bullet.js.map +1 -1
  12. package/dist/charts/charts.js.map +1 -1
  13. package/dist/charts/config.d.ts +11 -11
  14. package/dist/charts/config.js +4 -4
  15. package/dist/charts/config.js.map +1 -1
  16. package/dist/charts/custom-chart.js.map +1 -1
  17. package/dist/charts/date-navigation.js +10 -10
  18. package/dist/charts/date-navigation.js.map +1 -1
  19. package/dist/charts/donut.js +1 -1
  20. package/dist/charts/donut.js.map +1 -1
  21. package/dist/charts/frame.d.ts +1 -1
  22. package/dist/charts/frame.js +4 -4
  23. package/dist/charts/frame.js.map +1 -1
  24. package/dist/charts/funnel.js.map +1 -1
  25. package/dist/charts/gauge.js +5 -5
  26. package/dist/charts/gauge.js.map +1 -1
  27. package/dist/charts/grouped-bar.js.map +1 -1
  28. package/dist/charts/heatmap-calendar.js +11 -11
  29. package/dist/charts/heatmap-calendar.js.map +1 -1
  30. package/dist/charts/heatmap-matrix.js +8 -8
  31. package/dist/charts/heatmap-matrix.js.map +1 -1
  32. package/dist/charts/item-list.js +1 -1
  33. package/dist/charts/item-list.js.map +1 -1
  34. package/dist/charts/legend.js +19 -19
  35. package/dist/charts/legend.js.map +1 -1
  36. package/dist/charts/line.js.map +1 -1
  37. package/dist/charts/palette.js +2 -2
  38. package/dist/charts/palette.js.map +1 -1
  39. package/dist/charts/radar.js.map +1 -1
  40. package/dist/charts/sample.js.map +1 -1
  41. package/dist/charts/sankey.js.map +1 -1
  42. package/dist/charts/series.js.map +1 -1
  43. package/dist/charts/slot-bar.js +2 -2
  44. package/dist/charts/slot-bar.js.map +1 -1
  45. package/dist/charts/sparkline.js +38 -23
  46. package/dist/charts/sparkline.js.map +1 -1
  47. package/dist/charts/stacked-bar.js.map +1 -1
  48. package/dist/charts/stat-card.d.ts +2 -2
  49. package/dist/charts/stat-card.js +61 -58
  50. package/dist/charts/stat-card.js.map +1 -1
  51. package/dist/charts/timeline.js +18 -9
  52. package/dist/charts/timeline.js.map +1 -1
  53. package/dist/charts/timeseries.js.map +1 -1
  54. package/dist/charts/tooltip.js +16 -16
  55. package/dist/charts/tooltip.js.map +1 -1
  56. package/dist/components/accordion.js +1 -1
  57. package/dist/components/accordion.js.map +1 -1
  58. package/dist/components/alert-dialog.js +4 -4
  59. package/dist/components/alert-dialog.js.map +1 -1
  60. package/dist/components/app-header.d.ts +5 -1
  61. package/dist/components/app-header.js +19 -11
  62. package/dist/components/app-header.js.map +1 -1
  63. package/dist/components/app-shell.d.ts +4 -1
  64. package/dist/components/app-shell.js +8 -5
  65. package/dist/components/app-shell.js.map +1 -1
  66. package/dist/components/approval-card.d.ts +13 -0
  67. package/dist/components/approval-card.js +161 -0
  68. package/dist/components/approval-card.js.map +1 -0
  69. package/dist/components/autocomplete.js.map +1 -1
  70. package/dist/components/avatar.d.ts +12 -0
  71. package/dist/components/avatar.js +39 -18
  72. package/dist/components/avatar.js.map +1 -1
  73. package/dist/components/badge.js +8 -8
  74. package/dist/components/badge.js.map +1 -1
  75. package/dist/components/banner.d.ts +2 -2
  76. package/dist/components/banner.js +9 -8
  77. package/dist/components/banner.js.map +1 -1
  78. package/dist/components/basalt-mark.js +1 -1
  79. package/dist/components/basalt-mark.js.map +1 -1
  80. package/dist/components/battery-meter.js +5 -5
  81. package/dist/components/battery-meter.js.map +1 -1
  82. package/dist/components/breadcrumbs.js +6 -6
  83. package/dist/components/breadcrumbs.js.map +1 -1
  84. package/dist/components/button.js +10 -10
  85. package/dist/components/button.js.map +1 -1
  86. package/dist/components/chat-bubble.js +4 -3
  87. package/dist/components/chat-bubble.js.map +1 -1
  88. package/dist/components/chat-composer.d.ts +21 -3
  89. package/dist/components/chat-composer.js +126 -60
  90. package/dist/components/chat-composer.js.map +1 -1
  91. package/dist/components/chat-header.js +6 -6
  92. package/dist/components/chat-header.js.map +1 -1
  93. package/dist/components/chat-inbox.js +34 -30
  94. package/dist/components/chat-inbox.js.map +1 -1
  95. package/dist/components/chat-markdown.d.ts +8 -0
  96. package/dist/components/chat-markdown.js +122 -0
  97. package/dist/components/chat-markdown.js.map +1 -0
  98. package/dist/components/chat-message.d.ts +26 -0
  99. package/dist/components/chat-message.js +145 -0
  100. package/dist/components/chat-message.js.map +1 -0
  101. package/dist/components/checkbox.js +11 -11
  102. package/dist/components/checkbox.js.map +1 -1
  103. package/dist/components/clipboard-text.js +3 -3
  104. package/dist/components/clipboard-text.js.map +1 -1
  105. package/dist/components/code.d.ts +22 -20
  106. package/dist/components/code.js +94 -32
  107. package/dist/components/code.js.map +1 -1
  108. package/dist/components/collapsible.js +8 -4
  109. package/dist/components/collapsible.js.map +1 -1
  110. package/dist/components/combobox.js.map +1 -1
  111. package/dist/components/command-palette.js +73 -47
  112. package/dist/components/command-palette.js.map +1 -1
  113. package/dist/components/confirm-dialog.d.ts +4 -1
  114. package/dist/components/confirm-dialog.js +20 -18
  115. package/dist/components/confirm-dialog.js.map +1 -1
  116. package/dist/components/context-cards.d.ts +15 -0
  117. package/dist/components/context-cards.js +148 -0
  118. package/dist/components/context-cards.js.map +1 -0
  119. package/dist/components/context-menu.d.ts +1 -1
  120. package/dist/components/context-menu.js +18 -14
  121. package/dist/components/context-menu.js.map +1 -1
  122. package/dist/components/data-table.d.ts +8 -2
  123. package/dist/components/data-table.js +161 -106
  124. package/dist/components/data-table.js.map +1 -1
  125. package/dist/components/date-picker.js +13 -13
  126. package/dist/components/date-picker.js.map +1 -1
  127. package/dist/components/delete-resource.js +1 -1
  128. package/dist/components/delete-resource.js.map +1 -1
  129. package/dist/components/description-list.js +3 -3
  130. package/dist/components/description-list.js.map +1 -1
  131. package/dist/components/dialog.d.ts +2 -2
  132. package/dist/components/dialog.js +8 -8
  133. package/dist/components/dialog.js.map +1 -1
  134. package/dist/components/diff-table.d.ts +15 -0
  135. package/dist/components/diff-table.js +146 -0
  136. package/dist/components/diff-table.js.map +1 -0
  137. package/dist/components/dock.js +2 -2
  138. package/dist/components/dock.js.map +1 -1
  139. package/dist/components/dropdown-menu.js +23 -18
  140. package/dist/components/dropdown-menu.js.map +1 -1
  141. package/dist/components/editable-nav-item.js +63 -58
  142. package/dist/components/editable-nav-item.js.map +1 -1
  143. package/dist/components/empty.js +6 -6
  144. package/dist/components/empty.js.map +1 -1
  145. package/dist/components/fab.js +1 -1
  146. package/dist/components/fab.js.map +1 -1
  147. package/dist/components/field.js +3 -3
  148. package/dist/components/field.js.map +1 -1
  149. package/dist/components/file-dropzone.js +7 -7
  150. package/dist/components/file-dropzone.js.map +1 -1
  151. package/dist/components/filter-bar.js +6 -6
  152. package/dist/components/filter-bar.js.map +1 -1
  153. package/dist/components/flow.js +4 -3
  154. package/dist/components/flow.js.map +1 -1
  155. package/dist/components/grid.d.ts +3 -1
  156. package/dist/components/grid.js +15 -8
  157. package/dist/components/grid.js.map +1 -1
  158. package/dist/components/hover-card.js +1 -1
  159. package/dist/components/hover-card.js.map +1 -1
  160. package/dist/components/icon-picker.d.ts +8 -2
  161. package/dist/components/icon-picker.js +75 -47
  162. package/dist/components/icon-picker.js.map +1 -1
  163. package/dist/components/inline-editable.js +6 -6
  164. package/dist/components/inline-editable.js.map +1 -1
  165. package/dist/components/input-area.js +3 -3
  166. package/dist/components/input-area.js.map +1 -1
  167. package/dist/components/input-group.js +5 -5
  168. package/dist/components/input-group.js.map +1 -1
  169. package/dist/components/input.js +4 -4
  170. package/dist/components/input.js.map +1 -1
  171. package/dist/components/label.js +3 -3
  172. package/dist/components/label.js.map +1 -1
  173. package/dist/components/layer-card.d.ts +9 -4
  174. package/dist/components/layer-card.js +72 -67
  175. package/dist/components/layer-card.js.map +1 -1
  176. package/dist/components/link.js.map +1 -1
  177. package/dist/components/loader.d.ts +16 -10
  178. package/dist/components/loader.js +46 -53
  179. package/dist/components/loader.js.map +1 -1
  180. package/dist/components/loading-screen.js +3 -3
  181. package/dist/components/loading-screen.js.map +1 -1
  182. package/dist/components/menu-bar.js +32 -27
  183. package/dist/components/menu-bar.js.map +1 -1
  184. package/dist/components/meter.d.ts +5 -5
  185. package/dist/components/meter.js +25 -12
  186. package/dist/components/meter.js.map +1 -1
  187. package/dist/components/multi-select.js +66 -62
  188. package/dist/components/multi-select.js.map +1 -1
  189. package/dist/components/navigation-menu.d.ts +2 -2
  190. package/dist/components/navigation-menu.js +22 -8
  191. package/dist/components/navigation-menu.js.map +1 -1
  192. package/dist/components/overlay.js +2 -2
  193. package/dist/components/overlay.js.map +1 -1
  194. package/dist/components/page-header.d.ts +3 -1
  195. package/dist/components/page-header.js +12 -12
  196. package/dist/components/page-header.js.map +1 -1
  197. package/dist/components/pagination.js +3 -3
  198. package/dist/components/pagination.js.map +1 -1
  199. package/dist/components/popover.js +18 -23
  200. package/dist/components/popover.js.map +1 -1
  201. package/dist/components/prompt-bar.d.ts +16 -0
  202. package/dist/components/prompt-bar.js +49 -0
  203. package/dist/components/prompt-bar.js.map +1 -0
  204. package/dist/components/radio.js +9 -9
  205. package/dist/components/radio.js.map +1 -1
  206. package/dist/components/recommendation-card.d.ts +13 -0
  207. package/dist/components/recommendation-card.js +123 -0
  208. package/dist/components/recommendation-card.js.map +1 -0
  209. package/dist/components/resource-list.js +1 -1
  210. package/dist/components/resource-list.js.map +1 -1
  211. package/dist/components/responsive-master-detail.js +7 -7
  212. package/dist/components/responsive-master-detail.js.map +1 -1
  213. package/dist/components/scroll-area.js +3 -3
  214. package/dist/components/scroll-area.js.map +1 -1
  215. package/dist/components/section-rule.d.ts +5 -3
  216. package/dist/components/section-rule.js +12 -12
  217. package/dist/components/section-rule.js.map +1 -1
  218. package/dist/components/segment-control.js +3 -3
  219. package/dist/components/segment-control.js.map +1 -1
  220. package/dist/components/select.js +47 -32
  221. package/dist/components/select.js.map +1 -1
  222. package/dist/components/sensitive-input.js +17 -19
  223. package/dist/components/sensitive-input.js.map +1 -1
  224. package/dist/components/separator.js.map +1 -1
  225. package/dist/components/sheet.d.ts +4 -4
  226. package/dist/components/sheet.js +12 -10
  227. package/dist/components/sheet.js.map +1 -1
  228. package/dist/components/sidebar.d.ts +3 -1
  229. package/dist/components/sidebar.js +150 -138
  230. package/dist/components/sidebar.js.map +1 -1
  231. package/dist/components/skeleton-line.d.ts +1 -1
  232. package/dist/components/skeleton-line.js +2 -2
  233. package/dist/components/skeleton-line.js.map +1 -1
  234. package/dist/components/slider.js +2 -2
  235. package/dist/components/slider.js.map +1 -1
  236. package/dist/components/stat-strip.js +5 -4
  237. package/dist/components/stat-strip.js.map +1 -1
  238. package/dist/components/switch.js +6 -6
  239. package/dist/components/switch.js.map +1 -1
  240. package/dist/components/table-of-contents.js +5 -5
  241. package/dist/components/table-of-contents.js.map +1 -1
  242. package/dist/components/table-pager.js +2 -2
  243. package/dist/components/table-pager.js.map +1 -1
  244. package/dist/components/table.js +4 -4
  245. package/dist/components/table.js.map +1 -1
  246. package/dist/components/tabs.js +7 -6
  247. package/dist/components/tabs.js.map +1 -1
  248. package/dist/components/tag-badge.d.ts +10 -10
  249. package/dist/components/tag-badge.js +11 -11
  250. package/dist/components/tag-badge.js.map +1 -1
  251. package/dist/components/tag-color-picker.d.ts +8 -1
  252. package/dist/components/tag-color-picker.js +33 -25
  253. package/dist/components/tag-color-picker.js.map +1 -1
  254. package/dist/components/text.js +5 -5
  255. package/dist/components/text.js.map +1 -1
  256. package/dist/components/theme-toggle.js +1 -1
  257. package/dist/components/theme-toggle.js.map +1 -1
  258. package/dist/components/thinking.d.ts +16 -0
  259. package/dist/components/thinking.js +85 -0
  260. package/dist/components/thinking.js.map +1 -0
  261. package/dist/components/toast.js +25 -20
  262. package/dist/components/toast.js.map +1 -1
  263. package/dist/components/toggle-group.js +6 -5
  264. package/dist/components/toggle-group.js.map +1 -1
  265. package/dist/components/toggle.js +6 -6
  266. package/dist/components/toggle.js.map +1 -1
  267. package/dist/components/tool-chips.d.ts +12 -0
  268. package/dist/components/tool-chips.js +138 -0
  269. package/dist/components/tool-chips.js.map +1 -0
  270. package/dist/components/toolbar.js +3 -3
  271. package/dist/components/toolbar.js.map +1 -1
  272. package/dist/components/tooltip.js +1 -1
  273. package/dist/components/tooltip.js.map +1 -1
  274. package/dist/components/typeahead-field.js +59 -56
  275. package/dist/components/typeahead-field.js.map +1 -1
  276. package/dist/components/upload-queue.js +15 -14
  277. package/dist/components/upload-queue.js.map +1 -1
  278. package/dist/models/agent-feedback.d.ts +44 -0
  279. package/dist/models/agent-feedback.js +28 -0
  280. package/dist/models/agent-feedback.js.map +1 -0
  281. package/dist/models/avatar.d.ts +2 -0
  282. package/dist/models/avatar.js +15 -0
  283. package/dist/models/avatar.js.map +1 -0
  284. package/dist/models/code.d.ts +6 -0
  285. package/dist/models/code.js +24 -0
  286. package/dist/models/code.js.map +1 -0
  287. package/dist/models/context-cards.d.ts +13 -0
  288. package/dist/models/context-cards.js +17 -0
  289. package/dist/models/context-cards.js.map +1 -0
  290. package/dist/models/diff-table.d.ts +12 -0
  291. package/dist/models/diff-table.js +9 -0
  292. package/dist/models/diff-table.js.map +1 -0
  293. package/dist/models/recommendation.d.ts +26 -0
  294. package/dist/models/recommendation.js +23 -0
  295. package/dist/models/recommendation.js.map +1 -0
  296. package/dist/providers/accent.js +1 -1
  297. package/dist/providers/accent.js.map +1 -1
  298. package/dist/providers/link.js.map +1 -1
  299. package/dist/providers/theme.js +1 -1
  300. package/dist/providers/theme.js.map +1 -1
  301. package/dist/styles/base.css +128 -0
  302. package/dist/styles/standalone.css +1994 -937
  303. package/dist/styles/tailwind.css +179 -13
  304. package/dist/styles/tokens.css +679 -20
  305. package/dist/utils/cn.js +25 -4
  306. package/dist/utils/cn.js.map +1 -1
  307. package/dist/utils/control-surface.d.ts +1 -1
  308. package/dist/utils/control-surface.js +1 -1
  309. package/dist/utils/control-surface.js.map +1 -1
  310. package/dist/utils/navigation.d.ts +3 -0
  311. package/dist/utils/navigation.js +8 -0
  312. package/dist/utils/navigation.js.map +1 -0
  313. package/dist/utils/preference-store.js +1 -1
  314. package/dist/utils/preference-store.js.map +1 -1
  315. package/dist/utils/selection-indicator.d.ts +1 -1
  316. package/dist/utils/selection-indicator.js +49 -72
  317. package/dist/utils/selection-indicator.js.map +1 -1
  318. package/dist/utils/use-checkable-group.js.map +1 -1
  319. package/dist/utils/use-hover-highlight.d.ts +4 -0
  320. package/dist/utils/use-hover-highlight.js +80 -0
  321. package/dist/utils/use-hover-highlight.js.map +1 -0
  322. package/dist/viewmodels/use-approval-card.d.ts +20 -0
  323. package/dist/viewmodels/use-approval-card.js +83 -0
  324. package/dist/viewmodels/use-approval-card.js.map +1 -0
  325. package/dist/viewmodels/use-chat-composer.d.ts +16 -0
  326. package/dist/viewmodels/use-chat-composer.js +34 -0
  327. package/dist/viewmodels/use-chat-composer.js.map +1 -0
  328. package/dist/viewmodels/use-chat-message.d.ts +16 -0
  329. package/dist/viewmodels/use-chat-message.js +26 -0
  330. package/dist/viewmodels/use-chat-message.js.map +1 -0
  331. package/dist/viewmodels/use-code-block.d.ts +8 -0
  332. package/dist/viewmodels/use-code-block.js +38 -0
  333. package/dist/viewmodels/use-code-block.js.map +1 -0
  334. package/dist/viewmodels/use-context-cards.d.ts +17 -0
  335. package/dist/viewmodels/use-context-cards.js +18 -0
  336. package/dist/viewmodels/use-context-cards.js.map +1 -0
  337. package/dist/viewmodels/use-diff-table.d.ts +16 -0
  338. package/dist/viewmodels/use-diff-table.js +42 -0
  339. package/dist/viewmodels/use-diff-table.js.map +1 -0
  340. package/dist/viewmodels/use-loader.d.ts +4 -0
  341. package/dist/viewmodels/use-loader.js +22 -0
  342. package/dist/viewmodels/use-loader.js.map +1 -0
  343. package/dist/viewmodels/use-recommendation-card.d.ts +17 -0
  344. package/dist/viewmodels/use-recommendation-card.js +41 -0
  345. package/dist/viewmodels/use-recommendation-card.js.map +1 -0
  346. package/dist/viewmodels/use-thinking.d.ts +13 -0
  347. package/dist/viewmodels/use-thinking.js +18 -0
  348. package/dist/viewmodels/use-thinking.js.map +1 -0
  349. package/dist/viewmodels/use-tool-chips.d.ts +10 -0
  350. package/dist/viewmodels/use-tool-chips.js +20 -0
  351. package/dist/viewmodels/use-tool-chips.js.map +1 -0
  352. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"heatmap-matrix.js","names":[],"sources":["../../src/charts/heatmap-matrix.tsx"],"sourcesContent":["import {\n\ttype ComponentProps,\n\ttype FocusEvent,\n\tforwardRef,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { heatmapColorScales } from \"./heatmap-calendar\";\n\nexport type HeatmapMatrixValue = number | null | undefined;\n\nexport interface HeatmapMatrixCellContext {\n\trowIndex: number;\n\tcolIndex: number;\n\trowLabel: string;\n\tcolumnLabel: string;\n\tvalue: HeatmapMatrixValue;\n\tformattedValue: string;\n\tisMissing: boolean;\n\tcolorIndex: number;\n}\n\nexport interface HeatmapMatrixProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Ordered row labels (e.g. weekdays [\"Mon\", \"Tue\", ...], service tiers, or regions).\n\t */\n\trowLabels: readonly string[];\n\t/**\n\t * Ordered column labels (e.g. 24 hours [\"00:00\", ...], days, or status buckets).\n\t */\n\tcolumnLabels: readonly string[];\n\t/**\n\t * 2D matrix of values indexed by [rowIndex][colIndex].\n\t * Supports ragged rows, null, undefined, and non-finite values (treated as missing).\n\t * Numeric `0` is a valid reading and distinct from missing data.\n\t */\n\tvalues: readonly (readonly HeatmapMatrixValue[])[];\n\t/**\n\t * Explicit [min, max] domain for color intensity scaling.\n\t * If reversed [max, min], bounds are automatically normalized to [min, max].\n\t * If equal [v, v], values <= v receive level 0 while values > v clamp to the highest level.\n\t * If non-finite or omitted, dynamically derived solely from visible finite numeric cells in the dataset (or [0, 0] if no finite values exist).\n\t * Values at or below min receive level 0; values >= max clamp to the highest level.\n\t */\n\tdomain?: readonly [min: number, max: number];\n\t/**\n\t * Sequential color palette array from lowest to highest intensity.\n\t * If empty or single-color, gracefully resolves to base level.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for numeric values displayed in tooltips and accessible labels.\n\t * Defaults to `value.toLocaleString()`.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Placeholder string used for missing/null/undefined readings.\n\t * @default \"—\"\n\t */\n\tmissingLabel?: string;\n\t/**\n\t * Accessible label describing the matrix purpose or metric name.\n\t * @default \"Heatmap matrix\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Accessible name for the entire grid region.\n\t * @default \"Heatmap matrix\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Pixel height (and default width) of each matrix data cell.\n\t * @default 16\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel width of each matrix column / data cell.\n\t * When omitted, falls back to `cellSize` for square cells.\n\t * Allows wider rectangular cells to fit readable column headers (e.g. timestamps or service names).\n\t */\n\tcolumnWidth?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * Text for lowest bound legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Text for highest bound legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Whether to show the bottom intensity scale legend.\n\t * @default true\n\t */\n\tshowLegend?: boolean;\n\t/**\n\t * Custom cell tooltip content renderer.\n\t * If provided, replaces the default tooltip contents.\n\t */\n\trenderTooltip?: (cell: HeatmapMatrixCellContext) => ReactNode;\n}\n\nfunction resolveColorIndex(\n\tvalue: HeatmapMatrixValue,\n\tmin: number,\n\tmax: number,\n\tcolorScaleLength: number,\n): number {\n\tif (value == null || typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn -1; // missing indicator\n\t}\n\tif (colorScaleLength <= 1) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScaleLength - 1;\n\tif (max <= min) {\n\t\treturn value > min ? levels : 0;\n\t}\n\tconst clamped = Math.max(min, Math.min(max, value));\n\tconst normalized = (clamped - min) / (max - min);\n\tif (normalized <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(levels, Math.ceil(normalized * levels));\n}\n\nexport const HeatmapMatrix = forwardRef<HTMLDivElement, HeatmapMatrixProps>(function HeatmapMatrix(\n\t{\n\t\trowLabels,\n\t\tcolumnLabels,\n\t\tvalues,\n\t\tdomain,\n\t\tcolorScale = heatmapColorScales.green,\n\t\tvalueFormatter = (val) => val.toLocaleString(),\n\t\tmissingLabel = \"—\",\n\t\tmetricLabel = \"Heatmap matrix\",\n\t\tariaLabel = \"Heatmap matrix\",\n\t\tcellSize = 16,\n\t\tcolumnWidth,\n\t\tcellGap = 2,\n\t\tlessLabel = \"Less\",\n\t\tmoreLabel = \"More\",\n\t\tshowLegend = true,\n\t\trenderTooltip,\n\t\tclassName,\n\t\tstyle,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonKeyDown,\n\t\t...rest\n\t},\n\tref,\n) {\n\tconst matrixId = useId();\n\tconst numRows = rowLabels.length;\n\tconst numCols = columnLabels.length;\n\tconst effectiveColWidth = columnWidth ?? cellSize;\n\n\t// Derive domain restricted to visible row/col matrix bounds\n\tconst [minVal, maxVal] = useMemo(() => {\n\t\tif (domain) {\n\t\t\tconst [d0, d1] = domain;\n\t\t\tif (Number.isFinite(d0) && Number.isFinite(d1)) {\n\t\t\t\treturn [Math.min(d0, d1), Math.max(d0, d1)];\n\t\t\t}\n\t\t}\n\t\tlet lowest = Number.POSITIVE_INFINITY;\n\t\tlet highest = Number.NEGATIVE_INFINITY;\n\t\tfor (let r = 0; r < numRows; r++) {\n\t\t\tconst row = values[r];\n\t\t\tif (!row) continue;\n\t\t\tfor (let c = 0; c < numCols; c++) {\n\t\t\t\tconst v = row[c];\n\t\t\t\tif (typeof v === \"number\" && Number.isFinite(v)) {\n\t\t\t\t\tif (v < lowest) lowest = v;\n\t\t\t\t\tif (v > highest) highest = v;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!Number.isFinite(lowest) || !Number.isFinite(highest)) {\n\t\t\treturn [0, 0];\n\t\t}\n\t\treturn [lowest, highest];\n\t}, [domain, values, numRows, numCols]);\n\n\t// Focus state: active cell position [rowIndex, colIndex]\n\tconst [activePos, setActivePos] = useState<[number, number]>([0, 0]);\n\tconst [openTooltipPos, setOpenTooltipPos] = useState<string | null>(null);\n\tconst dismissedByEscapeRef = useRef(false);\n\n\tconst activePosRef = useRef<[number, number]>([0, 0]);\n\tactivePosRef.current = activePos;\n\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// Clamp active position when dimensions change\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (numRows === 0 || numCols === 0) {\n\t\t\tsetActivePos(([curR, curC]) => {\n\t\t\t\tif (curR === 0 && curC === 0) return [curR, curC];\n\t\t\t\treturn [0, 0];\n\t\t\t});\n\t\t\tsetOpenTooltipPos(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst [curR, curC] = activePosRef.current;\n\t\tconst nextR = Math.min(numRows - 1, Math.max(0, curR));\n\t\tconst nextC = Math.min(numCols - 1, Math.max(0, curC));\n\n\t\tsetActivePos((prev) => {\n\t\t\tif (prev[0] === nextR && prev[1] === nextC) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\treturn [nextR, nextC];\n\t\t});\n\n\t\tif (hadFocus) {\n\t\t\tconst key = `${nextR}-${nextC}`;\n\t\t\tconst target = cellRefs.current.get(key);\n\t\t\tif (target && document.activeElement !== target) {\n\t\t\t\ttarget.focus();\n\t\t\t}\n\t\t}\n\t}, [numRows, numCols]);\n\n\tconst handleContainerKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (e.key === \"Escape\") {\n\t\t\tdismissedByEscapeRef.current = true;\n\t\t\tsetOpenTooltipPos(null);\n\t\t}\n\n\t\t// Call caller onKeyDown first so caller can inspect or preventDefault\n\t\tonKeyDown?.(e);\n\t\tif (e.defaultPrevented) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (numRows === 0 || numCols === 0) return;\n\t\tif (e.key === \"Escape\") return;\n\n\t\tconst [currentRow, currentCol] = activePosRef.current;\n\t\tlet nextR = currentRow;\n\t\tlet nextC = currentCol;\n\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextC = Math.min(numCols - 1, currentCol + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextC = Math.max(0, currentCol - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextR = Math.min(numRows - 1, currentRow + 1);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextR = Math.max(0, currentRow - 1);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextC = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextC = numCols - 1;\n\t\t} else if (e.key === \"PageUp\") {\n\t\t\tnextR = 0;\n\t\t} else if (e.key === \"PageDown\") {\n\t\t\tnextR = numRows - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tdismissedByEscapeRef.current = false;\n\t\tsetActivePos([nextR, nextC]);\n\t\tconst nextKey = `${nextR}-${nextC}`;\n\t\tsetOpenTooltipPos(nextKey);\n\t\tconst targetButton = cellRefs.current.get(nextKey);\n\t\tif (targetButton) {\n\t\t\ttargetButton.focus();\n\t\t\tconst scrollContainer = targetButton.closest<HTMLElement>(\n\t\t\t\t'[role=\"region\"][aria-label$=\"scrollable table\"]',\n\t\t\t);\n\t\t\tconst rowHeader = targetButton.closest(\"tr\")?.querySelector<HTMLElement>('th[scope=\"row\"]');\n\n\t\t\tif (scrollContainer) {\n\t\t\t\tconst containerRect = scrollContainer.getBoundingClientRect();\n\t\t\t\tconst btnRect = targetButton.getBoundingClientRect();\n\t\t\t\tconst stickyWidth = rowHeader ? rowHeader.getBoundingClientRect().width : 0;\n\n\t\t\t\tconst visibleLeft = containerRect.left + stickyWidth;\n\t\t\t\tconst visibleRight = containerRect.right;\n\n\t\t\t\tif (btnRect.left < visibleLeft) {\n\t\t\t\t\tscrollContainer.scrollLeft -= visibleLeft - btnRect.left + cellGap;\n\t\t\t\t} else if (btnRect.right > visibleRight) {\n\t\t\t\t\tscrollContainer.scrollLeft += btnRect.right - visibleRight + cellGap;\n\t\t\t\t}\n\t\t\t} else if (typeof targetButton.scrollIntoView === \"function\") {\n\t\t\t\ttargetButton.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleContainerFocus = (e: FocusEvent<HTMLDivElement>) => {\n\t\tisFocusedInsideRef.current = true;\n\t\tonFocus?.(e);\n\t};\n\n\tconst handleContainerBlur = (e: FocusEvent<HTMLDivElement>) => {\n\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\tisFocusedInsideRef.current = false;\n\t\t\tdismissedByEscapeRef.current = false;\n\t\t}\n\t\tonBlur?.(e);\n\t};\n\n\tconst callerCleanupRef = useRef<(() => void) | undefined>(undefined);\n\n\tconst setRootRef = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\tcontainerRef.current = node;\n\n\t\t\tif (callerCleanupRef.current) {\n\t\t\t\tcallerCleanupRef.current();\n\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t}\n\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tconst cleanup = ref(node);\n\t\t\t\tif (typeof cleanup === \"function\") {\n\t\t\t\t\tcallerCleanupRef.current = cleanup;\n\t\t\t\t}\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tcontainerRef.current = null;\n\t\t\t\tif (callerCleanupRef.current) {\n\t\t\t\t\tcallerCleanupRef.current();\n\t\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t\t} else if (typeof ref === \"function\") {\n\t\t\t\t\tref(null);\n\t\t\t\t} else if (ref) {\n\t\t\t\t\tref.current = null;\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t[ref],\n\t);\n\n\tconst isEmpty = numRows === 0 || numCols === 0;\n\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<div\n\t\t\t\tref={setRootRef}\n\t\t\t\ttabIndex={isEmpty ? -1 : undefined}\n\t\t\t\trole=\"region\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tdata-testid=\"heatmap-matrix\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col gap-2 rounded-lg border border-basalt-border/60 bg-basalt-card p-3 text-xs outline-none\",\n\t\t\t\t\tisEmpty ? \"text-basalt-muted-foreground\" : \"text-basalt-foreground\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tstyle={style}\n\t\t\t\tonFocus={handleContainerFocus}\n\t\t\t\tonBlur={handleContainerBlur}\n\t\t\t\tonKeyDown={handleContainerKeyDown}\n\t\t\t\t{...rest}\n\t\t\t>\n\t\t\t\t{isEmpty ? (\n\t\t\t\t\t<span className=\"italic\">{missingLabel}</span>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Scrollable table container */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\trole=\"region\"\n\t\t\t\t\t\t\taria-label={`${ariaLabel} scrollable table`}\n\t\t\t\t\t\t\tclassName=\"w-full overflow-x-auto outline-none\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<table\n\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: W3C ARIA interactive 2D grid table with descendant roving tab buttons\n\t\t\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\t\t\tclassName=\"border-separate\"\n\t\t\t\t\t\t\t\tstyle={{ borderSpacing: cellGap }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t{/* Top-left empty header */}\n\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card p-0 text-left font-normal\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ minWidth: 64 }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Row \\ Column</span>\n\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t{columnLabels.map((col, colIdx) => (\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tkey={`${matrixId}-col-${colIdx}`}\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"p-0 text-center font-mono text-[10px] text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={col}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{col}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t{rowLabels.map((rowName, rowIdx) => (\n\t\t\t\t\t\t\t\t\t\t<tr key={`${matrixId}-row-${rowIdx}`}>\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card pr-2 text-left font-medium text-basalt-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize}px`,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminWidth: 64,\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{rowName}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t\t{columnLabels.map((colName, colIdx) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellKey = `${rowIdx}-${colIdx}`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst rawVal = values[rowIdx]?.[colIdx];\n\t\t\t\t\t\t\t\t\t\t\t\tconst isMissing =\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal == null || typeof rawVal !== \"number\" || !Number.isFinite(rawVal);\n\t\t\t\t\t\t\t\t\t\t\t\tconst colorIdx = resolveColorIndex(\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorScale.length,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst formattedVal = isMissing\n\t\t\t\t\t\t\t\t\t\t\t\t\t? missingLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: valueFormatter(rawVal as number);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellBg =\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIdx < 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"hsl(var(--basalt-muted) / 0.4)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: (colorScale[colorIdx] ?? \"hsl(var(--basalt-muted))\");\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst accessibleCellLabel = `${rowName}, ${colName}: ${formattedVal} (${metricLabel})`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isSelected = activePos[0] === rowIdx && activePos[1] === colIdx;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipPos === cellKey;\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellContext: HeatmapMatrixCellContext = {\n\t\t\t\t\t\t\t\t\t\t\t\t\trowIndex: rowIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolIndex: colIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\trowLabel: rowName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolumnLabel: colName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: rawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tformattedValue: formattedVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tisMissing,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIndex: colorIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: ARIA gridcell container wrapping roving interactive button\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/useFocusableInteractive: Focus is managed on child button via roving tabindex\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td key={cellKey} role=\"gridcell\" className=\"p-0 text-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!dismissedByEscapeRef.current) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== cellKey) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (dismissedByEscapeRef.current) return null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current.get(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) cellRefs.current.set(cellKey, el);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\telse cellRefs.current.delete(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={accessibleCellLabel}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttabIndex={isSelected ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActivePos([rowIdx, colIdx]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = false;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => (curr === cellKey ? null : curr));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"box-border block cursor-pointer rounded-xs border-0 p-0 transition-colors hover:ring-1 hover:ring-basalt-foreground focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-basalt-ring\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: cellBg,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tid={`${matrixId}-${cellKey}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonEscapeKeyDown={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{renderTooltip ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenderTooltip(cellContext)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-xs\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-semibold text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{rowName} · {colName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{metricLabel}:{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{formattedVal}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Legend footer */}\n\t\t\t\t\t\t{showLegend ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"mt-1 flex items-center justify-end gap-1 text-[11px] text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-xs\"\n\t\t\t\t\t\t\t\t\ttitle=\"Missing data\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: \"hsl(var(--basalt-muted) / 0.4)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{colorScale.map((color, idx) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tkey={`${color}-${idx}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-xs\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</TooltipProvider>\n\t);\n});\n\nHeatmapMatrix.displayName = \"HeatmapMatrix\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"heatmap-matrix.js","names":["_Fragment","Fragment$1","resolveColorIndex","value","colorScaleLength","levels","max","min","normalized","HeatmapMatrix","forwardRef","heatmapColorScales","val","rest","matrixId","useId","numRows","rowLabels","numCols","columnLabels","effectiveColWidth","columnWidth","cellSize","minVal","maxVal","useMemo","domain","d0","d1","lowest","highest","r","row","values","c","v","activePos","setActivePos","useState","openTooltipPos","setOpenTooltipPos","dismissedByEscapeRef","useRef","activePosRef","containerRef","cellRefs","isFocusedInsideRef","hadFocus","curR","curC","nextR","nextC","prev","key","target","handleContainerKeyDown","onKeyDown","currentRow","currentCol","nextKey","targetButton","scrollContainer","rowHeader","containerRect","btnRect","stickyWidth","visibleLeft","visibleRight","cellGap","handleContainerFocus","onFocus","handleContainerBlur","onBlur","callerCleanupRef","setRootRef","useCallback","node","ref","cleanup","isEmpty","TooltipProvider","ariaLabel","cn","className","missingLabel","col","colIdx","rowName","cellKey","rowIdx","rawVal","isMissing","colorIdx","colorScale","formattedVal","valueFormatter","cellBg","accessibleCellLabel","colName","metricLabel","isSelected","isOpen","cellContext","Tooltip","next","curr","TooltipTrigger","el","TooltipContent","renderTooltip","showLegend","lessLabel","color","idx","moreLabel"],"sources":["../../src/charts/heatmap-matrix.tsx"],"sourcesContent":["import {\n\ttype ComponentProps,\n\ttype FocusEvent,\n\tforwardRef,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { heatmapColorScales } from \"./heatmap-calendar\";\n\nexport type HeatmapMatrixValue = number | null | undefined;\n\nexport interface HeatmapMatrixCellContext {\n\trowIndex: number;\n\tcolIndex: number;\n\trowLabel: string;\n\tcolumnLabel: string;\n\tvalue: HeatmapMatrixValue;\n\tformattedValue: string;\n\tisMissing: boolean;\n\tcolorIndex: number;\n}\n\nexport interface HeatmapMatrixProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Ordered row labels (e.g. weekdays [\"Mon\", \"Tue\", ...], service tiers, or regions).\n\t */\n\trowLabels: readonly string[];\n\t/**\n\t * Ordered column labels (e.g. 24 hours [\"00:00\", ...], days, or status buckets).\n\t */\n\tcolumnLabels: readonly string[];\n\t/**\n\t * 2D matrix of values indexed by [rowIndex][colIndex].\n\t * Supports ragged rows, null, undefined, and non-finite values (treated as missing).\n\t * Numeric `0` is a valid reading and distinct from missing data.\n\t */\n\tvalues: readonly (readonly HeatmapMatrixValue[])[];\n\t/**\n\t * Explicit [min, max] domain for color intensity scaling.\n\t * If reversed [max, min], bounds are automatically normalized to [min, max].\n\t * If equal [v, v], values <= v receive level 0 while values > v clamp to the highest level.\n\t * If non-finite or omitted, dynamically derived solely from visible finite numeric cells in the dataset (or [0, 0] if no finite values exist).\n\t * Values at or below min receive level 0; values >= max clamp to the highest level.\n\t */\n\tdomain?: readonly [min: number, max: number];\n\t/**\n\t * Sequential color palette array from lowest to highest intensity.\n\t * If empty or single-color, gracefully resolves to base level.\n\t * @default heatmapColorScales.green\n\t */\n\tcolorScale?: readonly string[];\n\t/**\n\t * Formatter for numeric values displayed in tooltips and accessible labels.\n\t * Defaults to `value.toLocaleString()`.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Placeholder string used for missing/null/undefined readings.\n\t * @default \"—\"\n\t */\n\tmissingLabel?: string;\n\t/**\n\t * Accessible label describing the matrix purpose or metric name.\n\t * @default \"Heatmap matrix\"\n\t */\n\tmetricLabel?: string;\n\t/**\n\t * Accessible name for the entire grid region.\n\t * @default \"Heatmap matrix\"\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Pixel height (and default width) of each matrix data cell.\n\t * @default 16\n\t */\n\tcellSize?: number;\n\t/**\n\t * Pixel width of each matrix column / data cell.\n\t * When omitted, falls back to `cellSize` for square cells.\n\t * Allows wider rectangular cells to fit readable column headers (e.g. timestamps or service names).\n\t */\n\tcolumnWidth?: number;\n\t/**\n\t * Pixel gap between adjacent cells.\n\t * @default 2\n\t */\n\tcellGap?: number;\n\t/**\n\t * Text for lowest bound legend.\n\t * @default \"Less\"\n\t */\n\tlessLabel?: string;\n\t/**\n\t * Text for highest bound legend.\n\t * @default \"More\"\n\t */\n\tmoreLabel?: string;\n\t/**\n\t * Whether to show the bottom intensity scale legend.\n\t * @default true\n\t */\n\tshowLegend?: boolean;\n\t/**\n\t * Custom cell tooltip content renderer.\n\t * If provided, replaces the default tooltip contents.\n\t */\n\trenderTooltip?: (cell: HeatmapMatrixCellContext) => ReactNode;\n}\n\nfunction resolveColorIndex(\n\tvalue: HeatmapMatrixValue,\n\tmin: number,\n\tmax: number,\n\tcolorScaleLength: number,\n): number {\n\tif (value == null || typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\treturn -1; // missing indicator\n\t}\n\tif (colorScaleLength <= 1) {\n\t\treturn 0;\n\t}\n\tconst levels = colorScaleLength - 1;\n\tif (max <= min) {\n\t\treturn value > min ? levels : 0;\n\t}\n\tconst clamped = Math.max(min, Math.min(max, value));\n\tconst normalized = (clamped - min) / (max - min);\n\tif (normalized <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(levels, Math.ceil(normalized * levels));\n}\n\nexport const HeatmapMatrix = forwardRef<HTMLDivElement, HeatmapMatrixProps>(function HeatmapMatrix(\n\t{\n\t\trowLabels,\n\t\tcolumnLabels,\n\t\tvalues,\n\t\tdomain,\n\t\tcolorScale = heatmapColorScales.green,\n\t\tvalueFormatter = (val) => val.toLocaleString(),\n\t\tmissingLabel = \"—\",\n\t\tmetricLabel = \"Heatmap matrix\",\n\t\tariaLabel = \"Heatmap matrix\",\n\t\tcellSize = 16,\n\t\tcolumnWidth,\n\t\tcellGap = 2,\n\t\tlessLabel = \"Less\",\n\t\tmoreLabel = \"More\",\n\t\tshowLegend = true,\n\t\trenderTooltip,\n\t\tclassName,\n\t\tstyle,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonKeyDown,\n\t\t...rest\n\t},\n\tref,\n) {\n\tconst matrixId = useId();\n\tconst numRows = rowLabels.length;\n\tconst numCols = columnLabels.length;\n\tconst effectiveColWidth = columnWidth ?? cellSize;\n\n\t// Derive domain restricted to visible row/col matrix bounds\n\tconst [minVal, maxVal] = useMemo(() => {\n\t\tif (domain) {\n\t\t\tconst [d0, d1] = domain;\n\t\t\tif (Number.isFinite(d0) && Number.isFinite(d1)) {\n\t\t\t\treturn [Math.min(d0, d1), Math.max(d0, d1)];\n\t\t\t}\n\t\t}\n\t\tlet lowest = Number.POSITIVE_INFINITY;\n\t\tlet highest = Number.NEGATIVE_INFINITY;\n\t\tfor (let r = 0; r < numRows; r++) {\n\t\t\tconst row = values[r];\n\t\t\tif (!row) continue;\n\t\t\tfor (let c = 0; c < numCols; c++) {\n\t\t\t\tconst v = row[c];\n\t\t\t\tif (typeof v === \"number\" && Number.isFinite(v)) {\n\t\t\t\t\tif (v < lowest) lowest = v;\n\t\t\t\t\tif (v > highest) highest = v;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!Number.isFinite(lowest) || !Number.isFinite(highest)) {\n\t\t\treturn [0, 0];\n\t\t}\n\t\treturn [lowest, highest];\n\t}, [domain, values, numRows, numCols]);\n\n\t// Focus state: active cell position [rowIndex, colIndex]\n\tconst [activePos, setActivePos] = useState<[number, number]>([0, 0]);\n\tconst [openTooltipPos, setOpenTooltipPos] = useState<string | null>(null);\n\tconst dismissedByEscapeRef = useRef(false);\n\n\tconst activePosRef = useRef<[number, number]>([0, 0]);\n\tactivePosRef.current = activePos;\n\n\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\tconst cellRefs = useRef<Map<string, HTMLButtonElement>>(new Map());\n\tconst isFocusedInsideRef = useRef(false);\n\n\t// Clamp active position when dimensions change\n\tuseEffect(() => {\n\t\tconst hadFocus = isFocusedInsideRef.current;\n\t\tif (numRows === 0 || numCols === 0) {\n\t\t\tsetActivePos(([curR, curC]) => {\n\t\t\t\tif (curR === 0 && curC === 0) return [curR, curC];\n\t\t\t\treturn [0, 0];\n\t\t\t});\n\t\t\tsetOpenTooltipPos(null);\n\t\t\tif (hadFocus) {\n\t\t\t\tcontainerRef.current?.focus();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst [curR, curC] = activePosRef.current;\n\t\tconst nextR = Math.min(numRows - 1, Math.max(0, curR));\n\t\tconst nextC = Math.min(numCols - 1, Math.max(0, curC));\n\n\t\tsetActivePos((prev) => {\n\t\t\tif (prev[0] === nextR && prev[1] === nextC) {\n\t\t\t\treturn prev;\n\t\t\t}\n\t\t\treturn [nextR, nextC];\n\t\t});\n\n\t\tif (hadFocus) {\n\t\t\tconst key = `${nextR}-${nextC}`;\n\t\t\tconst target = cellRefs.current.get(key);\n\t\t\tif (target && document.activeElement !== target) {\n\t\t\t\ttarget.focus();\n\t\t\t}\n\t\t}\n\t}, [numRows, numCols]);\n\n\tconst handleContainerKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (e.key === \"Escape\") {\n\t\t\tdismissedByEscapeRef.current = true;\n\t\t\tsetOpenTooltipPos(null);\n\t\t}\n\n\t\t// Call caller onKeyDown first so caller can inspect or preventDefault\n\t\tonKeyDown?.(e);\n\t\tif (e.defaultPrevented) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (numRows === 0 || numCols === 0) return;\n\t\tif (e.key === \"Escape\") return;\n\n\t\tconst [currentRow, currentCol] = activePosRef.current;\n\t\tlet nextR = currentRow;\n\t\tlet nextC = currentCol;\n\n\t\tif (e.key === \"ArrowRight\") {\n\t\t\tnextC = Math.min(numCols - 1, currentCol + 1);\n\t\t} else if (e.key === \"ArrowLeft\") {\n\t\t\tnextC = Math.max(0, currentCol - 1);\n\t\t} else if (e.key === \"ArrowDown\") {\n\t\t\tnextR = Math.min(numRows - 1, currentRow + 1);\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\tnextR = Math.max(0, currentRow - 1);\n\t\t} else if (e.key === \"Home\") {\n\t\t\tnextC = 0;\n\t\t} else if (e.key === \"End\") {\n\t\t\tnextC = numCols - 1;\n\t\t} else if (e.key === \"PageUp\") {\n\t\t\tnextR = 0;\n\t\t} else if (e.key === \"PageDown\") {\n\t\t\tnextR = numRows - 1;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t\tdismissedByEscapeRef.current = false;\n\t\tsetActivePos([nextR, nextC]);\n\t\tconst nextKey = `${nextR}-${nextC}`;\n\t\tsetOpenTooltipPos(nextKey);\n\t\tconst targetButton = cellRefs.current.get(nextKey);\n\t\tif (targetButton) {\n\t\t\ttargetButton.focus();\n\t\t\tconst scrollContainer = targetButton.closest<HTMLElement>(\n\t\t\t\t'[role=\"region\"][aria-label$=\"scrollable table\"]',\n\t\t\t);\n\t\t\tconst rowHeader = targetButton.closest(\"tr\")?.querySelector<HTMLElement>('th[scope=\"row\"]');\n\n\t\t\tif (scrollContainer) {\n\t\t\t\tconst containerRect = scrollContainer.getBoundingClientRect();\n\t\t\t\tconst btnRect = targetButton.getBoundingClientRect();\n\t\t\t\tconst stickyWidth = rowHeader ? rowHeader.getBoundingClientRect().width : 0;\n\n\t\t\t\tconst visibleLeft = containerRect.left + stickyWidth;\n\t\t\t\tconst visibleRight = containerRect.right;\n\n\t\t\t\tif (btnRect.left < visibleLeft) {\n\t\t\t\t\tscrollContainer.scrollLeft -= visibleLeft - btnRect.left + cellGap;\n\t\t\t\t} else if (btnRect.right > visibleRight) {\n\t\t\t\t\tscrollContainer.scrollLeft += btnRect.right - visibleRight + cellGap;\n\t\t\t\t}\n\t\t\t} else if (typeof targetButton.scrollIntoView === \"function\") {\n\t\t\t\ttargetButton.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleContainerFocus = (e: FocusEvent<HTMLDivElement>) => {\n\t\tisFocusedInsideRef.current = true;\n\t\tonFocus?.(e);\n\t};\n\n\tconst handleContainerBlur = (e: FocusEvent<HTMLDivElement>) => {\n\t\tif (!e.currentTarget.contains(e.relatedTarget)) {\n\t\t\tisFocusedInsideRef.current = false;\n\t\t\tdismissedByEscapeRef.current = false;\n\t\t}\n\t\tonBlur?.(e);\n\t};\n\n\tconst callerCleanupRef = useRef<(() => void) | undefined>(undefined);\n\n\tconst setRootRef = useCallback(\n\t\t(node: HTMLDivElement | null) => {\n\t\t\tcontainerRef.current = node;\n\n\t\t\tif (callerCleanupRef.current) {\n\t\t\t\tcallerCleanupRef.current();\n\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t}\n\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tconst cleanup = ref(node);\n\t\t\t\tif (typeof cleanup === \"function\") {\n\t\t\t\t\tcallerCleanupRef.current = cleanup;\n\t\t\t\t}\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tcontainerRef.current = null;\n\t\t\t\tif (callerCleanupRef.current) {\n\t\t\t\t\tcallerCleanupRef.current();\n\t\t\t\t\tcallerCleanupRef.current = undefined;\n\t\t\t\t} else if (typeof ref === \"function\") {\n\t\t\t\t\tref(null);\n\t\t\t\t} else if (ref) {\n\t\t\t\t\tref.current = null;\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t[ref],\n\t);\n\n\tconst isEmpty = numRows === 0 || numCols === 0;\n\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<div\n\t\t\t\tref={setRootRef}\n\t\t\t\ttabIndex={isEmpty ? -1 : undefined}\n\t\t\t\trole=\"region\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tdata-testid=\"heatmap-matrix\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex flex-col gap-basalt-space-lg rounded-basalt-md border border-basalt-border/60 bg-basalt-card p-basalt-space-lg text-basalt-sm outline-none\",\n\t\t\t\t\tisEmpty ? \"text-basalt-muted-foreground\" : \"text-basalt-foreground\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tstyle={style}\n\t\t\t\tonFocus={handleContainerFocus}\n\t\t\t\tonBlur={handleContainerBlur}\n\t\t\t\tonKeyDown={handleContainerKeyDown}\n\t\t\t\t{...rest}\n\t\t\t>\n\t\t\t\t{isEmpty ? (\n\t\t\t\t\t<span className=\"italic\">{missingLabel}</span>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Scrollable table container */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\trole=\"region\"\n\t\t\t\t\t\t\taria-label={`${ariaLabel} scrollable table`}\n\t\t\t\t\t\t\tclassName=\"w-full overflow-x-auto outline-none\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<table\n\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: W3C ARIA interactive 2D grid table with descendant roving tab buttons\n\t\t\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\t\t\tclassName=\"border-separate\"\n\t\t\t\t\t\t\t\tstyle={{ borderSpacing: cellGap }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t{/* Top-left empty header */}\n\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card p-0 text-left font-normal\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ minWidth: 64 }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Row \\ Column</span>\n\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t{columnLabels.map((col, colIdx) => (\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tkey={`${matrixId}-col-${colIdx}`}\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"p-0 text-center font-mono text-basalt-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxWidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={col}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{col}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t{rowLabels.map((rowName, rowIdx) => (\n\t\t\t\t\t\t\t\t\t\t<tr key={`${matrixId}-row-${rowIdx}`}>\n\t\t\t\t\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\t\t\t\t\tscope=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"sticky left-0 z-10 bg-basalt-card pr-basalt-space-lg text-left font-medium text-basalt-foreground select-none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlineHeight: `${cellSize}px`,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminWidth: 64,\n\t\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{rowName}\n\t\t\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t\t\t\t{columnLabels.map((colName, colIdx) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellKey = `${rowIdx}-${colIdx}`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst rawVal = values[rowIdx]?.[colIdx];\n\t\t\t\t\t\t\t\t\t\t\t\tconst isMissing =\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal == null || typeof rawVal !== \"number\" || !Number.isFinite(rawVal);\n\t\t\t\t\t\t\t\t\t\t\t\tconst colorIdx = resolveColorIndex(\n\t\t\t\t\t\t\t\t\t\t\t\t\trawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tminVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tmaxVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorScale.length,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst formattedVal = isMissing\n\t\t\t\t\t\t\t\t\t\t\t\t\t? missingLabel\n\t\t\t\t\t\t\t\t\t\t\t\t\t: valueFormatter(rawVal as number);\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellBg =\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIdx < 0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? \"hsl(var(--basalt-muted) / 0.4)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: (colorScale[colorIdx] ?? \"hsl(var(--basalt-muted))\");\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst accessibleCellLabel = `${rowName}, ${colName}: ${formattedVal} (${metricLabel})`;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isSelected = activePos[0] === rowIdx && activePos[1] === colIdx;\n\t\t\t\t\t\t\t\t\t\t\t\tconst isOpen = openTooltipPos === cellKey;\n\n\t\t\t\t\t\t\t\t\t\t\t\tconst cellContext: HeatmapMatrixCellContext = {\n\t\t\t\t\t\t\t\t\t\t\t\t\trowIndex: rowIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolIndex: colIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t\trowLabel: rowName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolumnLabel: colName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: rawVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tformattedValue: formattedVal,\n\t\t\t\t\t\t\t\t\t\t\t\t\tisMissing,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcolorIndex: colorIdx,\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: ARIA gridcell container wrapping roving interactive button\n\t\t\t\t\t\t\t\t\t\t\t\t\t// biome-ignore lint/a11y/useFocusableInteractive: Focus is managed on child button via roving tabindex\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td key={cellKey} role=\"gridcell\" className=\"p-0 text-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Tooltip\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\topen={isOpen}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonOpenChange={(next) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (next) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!dismissedByEscapeRef.current) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (curr !== cellKey) return curr;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (dismissedByEscapeRef.current) return null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isCellFocused =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdocument.activeElement === cellRefs.current.get(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn isCellFocused ? curr : null;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tref={(el) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (el) cellRefs.current.set(cellKey, el);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\telse cellRefs.current.delete(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={accessibleCellLabel}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttabIndex={isSelected ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetActivePos([rowIdx, colIdx]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = false;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(cellKey);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos((curr) => (curr === cellKey ? null : curr));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"box-border block cursor-pointer rounded-basalt-sm border-0 p-0 transition-colors basalt-motion hover:ring-1 hover:ring-basalt-foreground focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-basalt-ring\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: effectiveColWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: cellBg,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tid={`${matrixId}-${cellKey}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonEscapeKeyDown={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdismissedByEscapeRef.current = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetOpenTooltipPos(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{renderTooltip ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenderTooltip(cellContext)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-sm\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"font-semibold text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{rowName} · {colName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{metricLabel}:{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium text-basalt-popover-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{formattedVal}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Legend footer */}\n\t\t\t\t\t\t{showLegend ? (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"mt-basalt-space-sm flex items-center justify-end gap-basalt-space-sm text-basalt-xs text-basalt-muted-foreground select-none\"\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{lessLabel}</span>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\ttitle=\"Missing data\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\tbackgroundColor: \"hsl(var(--basalt-muted) / 0.4)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{colorScale.map((color, idx) => (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tkey={`${color}-${idx}`}\n\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm\"\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\twidth: cellSize,\n\t\t\t\t\t\t\t\t\t\t\theight: cellSize,\n\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t<span>{moreLabel}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</TooltipProvider>\n\t);\n});\n\nHeatmapMatrix.displayName = \"HeatmapMatrix\";\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { jsx as t, jsxs as n } from "react/jsx-runtime";
4
4
  //#region src/charts/item-list.tsx
5
5
  function r({ items: r, ariaLabel: i = "Item list", className: a }) {
6
6
  return /* @__PURE__ */ t("ul", {
7
- className: e("space-y-1 text-sm", a),
7
+ className: e("space-y-basalt-space-sm text-basalt-base", a),
8
8
  "aria-label": i,
9
9
  children: r.map((e, t) => /* @__PURE__ */ n("li", { children: [e.label, e.value ? /* @__PURE__ */ n("span", {
10
10
  className: "text-basalt-muted-foreground",
@@ -1 +1 @@
1
- {"version":3,"file":"item-list.js","names":[],"sources":["../../src/charts/item-list.tsx"],"sourcesContent":["import { cn } from \"../utils/cn\";\n\nexport type ItemListItem = { id?: string; label: string; value?: string };\n\nexport type ItemListProps = {\n\titems: ItemListItem[];\n\tariaLabel?: string;\n\tclassName?: string;\n};\n\nexport function ItemList({ items, ariaLabel = \"Item list\", className }: ItemListProps) {\n\treturn (\n\t\t<ul className={cn(\"space-y-1 text-sm\", className)} aria-label={ariaLabel}>\n\t\t\t{items.map((item, index) => (\n\t\t\t\t<li key={item.id ?? `${item.label}-${item.value ?? \"\"}-${index}`}>\n\t\t\t\t\t{item.label}\n\t\t\t\t\t{item.value ? <span className=\"text-basalt-muted-foreground\"> {item.value}</span> : null}\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n"],"mappings":";;;;AAUA,SAAgB,EAAS,EAAE,UAAO,eAAY,aAAa,gBAA4B;CACtF,OACC,kBAAC,MAAD;EAAI,WAAW,EAAG,qBAAqB,CAAS;EAAG,cAAY;EAC7D,UAAA,EAAM,KAAK,GAAM,MACjB,kBAAC,MAAD,EAAA,UAAA,CACE,EAAK,OACL,EAAK,QAAQ,kBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CAA+C,KAAE,EAAK,KAAY;EAAI,CAAA,IAAA,IACjF,EAAA,GAHK,EAAK,MAAM,GAAG,EAAK,MAAM,GAAG,EAAK,SAAS,GAAG,GAAG,GAGrD,CACJ;CACE,CAAA;AAEN"}
1
+ {"version":3,"file":"item-list.js","names":["ItemList","cn","className","ariaLabel","items","item","index"],"sources":["../../src/charts/item-list.tsx"],"sourcesContent":["import { cn } from \"../utils/cn\";\n\nexport type ItemListItem = { id?: string; label: string; value?: string };\n\nexport type ItemListProps = {\n\titems: ItemListItem[];\n\tariaLabel?: string;\n\tclassName?: string;\n};\n\nexport function ItemList({ items, ariaLabel = \"Item list\", className }: ItemListProps) {\n\treturn (\n\t\t<ul\n\t\t\tclassName={cn(\"space-y-basalt-space-sm text-basalt-base\", className)}\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t{items.map((item, index) => (\n\t\t\t\t<li key={item.id ?? `${item.label}-${item.value ?? \"\"}-${index}`}>\n\t\t\t\t\t{item.label}\n\t\t\t\t\t{item.value ? <span className=\"text-basalt-muted-foreground\"> {item.value}</span> : null}\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n"],"mappings":";;;;AAUA,SAAgBA,EAAS,EAAE,UAAO,eAAY,aAAa,gBAA4B;CACtF,OACC,kBAAC,MAAD;EACC,WAAWC,EAAG,4CAA4CC,CAAS;EACnE,cAAYC;EAEX,UAAAC,EAAM,KAAK,GAAM,MACjB,kBAAC,MAAD,EAAA,UAAA,CACEC,EAAK,OACLA,EAAK,QAAQ,kBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CAA+C,KAAEA,EAAK,KAAY;EAAI,CAAA,IAAA,IACjF,EAAA,GAHKA,EAAK,MAAM,GAAGA,EAAK,MAAM,GAAGA,EAAK,SAAS,GAAG,GAAGC,GAGrD,CACJ;CACE,CAAA;AAEN"}
@@ -1,43 +1,43 @@
1
1
  "use client";
2
- import { CHART_TYPE as e, seriesColor as t } from "./config.js";
3
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
2
+ import { seriesColor as e } from "./config.js";
3
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
4
4
  //#region src/charts/legend.tsx
5
- function i({ items: i, shape: a = "line" }) {
6
- return i.length === 0 ? null : /* @__PURE__ */ n("div", {
5
+ function r({ items: r, shape: i = "line" }) {
6
+ return r.length === 0 ? null : /* @__PURE__ */ t("div", {
7
7
  "data-testid": "chart-legend",
8
8
  style: {
9
9
  color: "hsl(var(--basalt-muted-foreground))",
10
- columnGap: 16,
10
+ columnGap: "var(--basalt-space-default)",
11
11
  display: "flex",
12
12
  flexWrap: "wrap",
13
- fontSize: e.legendFontSize,
14
- marginTop: 12,
15
- rowGap: 4
13
+ fontSize: "var(--basalt-text-sm)",
14
+ marginTop: "var(--basalt-space-default)",
15
+ rowGap: "var(--basalt-space-sm)"
16
16
  },
17
- children: i.map((e, i) => {
18
- let o = t(e, i) ?? "hsl(var(--basalt-chart-1))", s = e.label ?? e.key;
19
- return /* @__PURE__ */ r("div", {
17
+ children: r.map((r, a) => {
18
+ let o = e(r, a) ?? "hsl(var(--basalt-chart-1))", s = r.label ?? r.key;
19
+ return /* @__PURE__ */ n("div", {
20
20
  style: {
21
21
  alignItems: "center",
22
22
  display: "flex",
23
- gap: 6
23
+ gap: "var(--basalt-space-md)"
24
24
  },
25
- children: [/* @__PURE__ */ n("svg", {
25
+ children: [/* @__PURE__ */ t("svg", {
26
26
  width: "18",
27
27
  height: "10",
28
28
  "aria-hidden": "true",
29
- children: a === "bar" ? /* @__PURE__ */ n("rect", {
29
+ children: i === "bar" ? /* @__PURE__ */ t("rect", {
30
30
  x: "1",
31
31
  y: "2",
32
32
  width: "16",
33
33
  height: "6",
34
34
  rx: "1",
35
35
  fill: o
36
- }) : a === "area" ? /* @__PURE__ */ n("polygon", {
36
+ }) : i === "area" ? /* @__PURE__ */ t("polygon", {
37
37
  points: "0,8 4,4 9,6 18,2 18,8",
38
38
  fill: o,
39
39
  opacity: "0.7"
40
- }) : /* @__PURE__ */ n("line", {
40
+ }) : /* @__PURE__ */ t("line", {
41
41
  x1: "0",
42
42
  y1: "5",
43
43
  x2: "18",
@@ -45,12 +45,12 @@ function i({ items: i, shape: a = "line" }) {
45
45
  stroke: o,
46
46
  strokeWidth: "2"
47
47
  })
48
- }), /* @__PURE__ */ n("span", { children: s })]
49
- }, e.key);
48
+ }), /* @__PURE__ */ t("span", { children: s })]
49
+ }, r.key);
50
50
  })
51
51
  });
52
52
  }
53
53
  //#endregion
54
- export { i as ChartLegend };
54
+ export { r as ChartLegend };
55
55
 
56
56
  //# sourceMappingURL=legend.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"legend.js","names":[],"sources":["../../src/charts/legend.tsx"],"sourcesContent":["import { CHART_TYPE, seriesColor } from \"./config\";\nimport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type ChartLegendShape = \"bar\" | \"line\" | \"area\";\n\nexport type ChartLegendProps = {\n\titems: ChartSeriesDescriptor[];\n\tshape?: ChartLegendShape;\n};\n\nexport function ChartLegend({ items, shape = \"line\" }: ChartLegendProps) {\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-legend\"\n\t\t\tstyle={{\n\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\tcolumnGap: 16,\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tfontSize: CHART_TYPE.legendFontSize,\n\t\t\t\tmarginTop: 12,\n\t\t\t\trowGap: 4,\n\t\t\t}}\n\t\t>\n\t\t\t{items.map((item, index) => {\n\t\t\t\tconst color = seriesColor(item, index) ?? \"hsl(var(--basalt-chart-1))\";\n\t\t\t\tconst label = item.label ?? item.key;\n\t\t\t\treturn (\n\t\t\t\t\t<div key={item.key} style={{ alignItems: \"center\", display: \"flex\", gap: 6 }}>\n\t\t\t\t\t\t<svg width=\"18\" height=\"10\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t{shape === \"bar\" ? (\n\t\t\t\t\t\t\t\t<rect x=\"1\" y=\"2\" width=\"16\" height=\"6\" rx=\"1\" fill={color} />\n\t\t\t\t\t\t\t) : shape === \"area\" ? (\n\t\t\t\t\t\t\t\t<polygon points=\"0,8 4,4 9,6 18,2 18,8\" fill={color} opacity=\"0.7\" />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<line x1=\"0\" y1=\"5\" x2=\"18\" y2=\"5\" stroke={color} strokeWidth=\"2\" />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<span>{label}</span>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AAUA,SAAgB,EAAY,EAAE,UAAO,WAAQ,UAA4B;CAIxE,OAHI,EAAM,WAAW,IACb,OAGP,kBAAC,OAAD;EACC,eAAY;EACZ,OAAO;GACN,OAAO;GACP,WAAW;GACX,SAAS;GACT,UAAU;GACV,UAAU,EAAW;GACrB,WAAW;GACX,QAAQ;EACT;EAEC,UAAA,EAAM,KAAK,GAAM,MAAU;GAC3B,IAAM,IAAQ,EAAY,GAAM,CAAK,KAAK,8BACpC,IAAQ,EAAK,SAAS,EAAK;GACjC,OACC,kBAAC,OAAD;IAAoB,OAAO;KAAE,YAAY;KAAU,SAAS;KAAQ,KAAK;IAAE;IAA3E,UAAA,CACC,kBAAC,OAAD;KAAK,OAAM;KAAK,QAAO;KAAK,eAAY;KACtC,UAAA,MAAU,QACV,kBAAC,QAAD;MAAM,GAAE;MAAI,GAAE;MAAI,OAAM;MAAK,QAAO;MAAI,IAAG;MAAI,MAAM;KAAQ,CAAA,IAC1D,MAAU,SACb,kBAAC,WAAD;MAAS,QAAO;MAAwB,MAAM;MAAO,SAAQ;KAAO,CAAA,IAEpE,kBAAC,QAAD;MAAM,IAAG;MAAI,IAAG;MAAI,IAAG;MAAK,IAAG;MAAI,QAAQ;MAAO,aAAY;KAAK,CAAA;IAEhE,CAAA,GACL,kBAAC,QAAD,EAAA,UAAO,EAAY,CAAA,CACf;GAXK,GAAA,EAAK,GAWV;EAEP,CAAC;CACG,CAAA;AAEP"}
1
+ {"version":3,"file":"legend.js","names":["ChartLegend","items","color","seriesColor","item","index","label","shape"],"sources":["../../src/charts/legend.tsx"],"sourcesContent":["import { seriesColor } from \"./config\";\nimport type { ChartSeriesDescriptor } from \"./series\";\n\nexport type ChartLegendShape = \"bar\" | \"line\" | \"area\";\n\nexport type ChartLegendProps = {\n\titems: ChartSeriesDescriptor[];\n\tshape?: ChartLegendShape;\n};\n\nexport function ChartLegend({ items, shape = \"line\" }: ChartLegendProps) {\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-legend\"\n\t\t\tstyle={{\n\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\tcolumnGap: \"var(--basalt-space-default)\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tfontSize: \"var(--basalt-text-sm)\",\n\t\t\t\tmarginTop: \"var(--basalt-space-default)\",\n\t\t\t\trowGap: \"var(--basalt-space-sm)\",\n\t\t\t}}\n\t\t>\n\t\t\t{items.map((item, index) => {\n\t\t\t\tconst color = seriesColor(item, index) ?? \"hsl(var(--basalt-chart-1))\";\n\t\t\t\tconst label = item.label ?? item.key;\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tstyle={{ alignItems: \"center\", display: \"flex\", gap: \"var(--basalt-space-md)\" }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<svg width=\"18\" height=\"10\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t{shape === \"bar\" ? (\n\t\t\t\t\t\t\t\t<rect x=\"1\" y=\"2\" width=\"16\" height=\"6\" rx=\"1\" fill={color} />\n\t\t\t\t\t\t\t) : shape === \"area\" ? (\n\t\t\t\t\t\t\t\t<polygon points=\"0,8 4,4 9,6 18,2 18,8\" fill={color} opacity=\"0.7\" />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<line x1=\"0\" y1=\"5\" x2=\"18\" y2=\"5\" stroke={color} strokeWidth=\"2\" />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<span>{label}</span>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AAUA,SAAgBA,EAAY,EAAE,UAAO,WAAQ,UAA4B;CAIxE,OAHIC,EAAM,WAAW,IACb,OAGP,kBAAC,OAAD;EACC,eAAY;EACZ,OAAO;GACN,OAAO;GACP,WAAW;GACX,SAAS;GACT,UAAU;GACV,UAAU;GACV,WAAW;GACX,QAAQ;EACT;EAEC,UAAAA,EAAM,KAAK,GAAM,MAAU;GAC3B,IAAMC,IAAQC,EAAYC,GAAMC,CAAK,KAAK,8BACpCC,IAAQF,EAAK,SAASA,EAAK;GACjC,OACC,kBAAC,OAAD;IAEC,OAAO;KAAE,YAAY;KAAU,SAAS;KAAQ,KAAK;IAAyB;IAF/E,UAAA,CAIC,kBAAC,OAAD;KAAK,OAAM;KAAK,QAAO;KAAK,eAAY;KACtC,UAAAG,MAAU,QACV,kBAAC,QAAD;MAAM,GAAE;MAAI,GAAE;MAAI,OAAM;MAAK,QAAO;MAAI,IAAG;MAAI,MAAML;KAAQ,CAAA,IAC1DK,MAAU,SACb,kBAAC,WAAD;MAAS,QAAO;MAAwB,MAAML;MAAO,SAAQ;KAAO,CAAA,IAEpE,kBAAC,QAAD;MAAM,IAAG;MAAI,IAAG;MAAI,IAAG;MAAK,IAAG;MAAI,QAAQA;MAAO,aAAY;KAAK,CAAA;IAEhE,CAAA,GACL,kBAAC,QAAD,EAAA,UAAOI,EAAY,CAAA,CACf;GAbC,GAAAF,EAAK,GAaN;EAEP,CAAC;CACG,CAAA;AAEP"}
@@ -1 +1 @@
1
- {"version":3,"file":"line.js","names":[],"sources":["../../src/charts/line.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { CartesianGrid, Line, LineChart as RechartsLine, Tooltip, XAxis, YAxis } from \"recharts\";\nimport {\n\tANIMATION_PROPS,\n\tCHART_PLOT_MARGIN,\n\tCHART_PLOT_MARGIN_BARE,\n\tCHART_TYPE,\n\tcartesianAxisProps,\n\tchartTooltipProps,\n\tGRID_PROPS,\n\tseriesColor,\n} from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport {\n\tapplyLeadColor,\n\ttype ChartSeriesDescriptor,\n\tresolveChartSeries,\n\ttype XYPoint,\n\txyFallbackKeys,\n} from \"./series\";\nimport type { ChartTooltipItem } from \"./tooltip\";\n\nexport type LineChartAxisDomain =\n\t| [number | \"auto\" | \"dataMin\", number | \"auto\" | \"dataMax\"]\n\t| readonly [number | \"auto\" | \"dataMin\", number | \"auto\" | \"dataMax\"];\n\nexport type LineChartNumericKeys<T> = {\n\t[K in keyof T]-?: K extends \"x\"\n\t\t? never\n\t\t: [NonNullable<T[K]>] extends [never]\n\t\t\t? never\n\t\t\t: NonNullable<T[K]> extends number\n\t\t\t\t? K extends string\n\t\t\t\t\t? K\n\t\t\t\t\t: never\n\t\t\t\t: never;\n}[keyof T];\n\nexport type LineChartLegendRenderer<K extends string = string> = (props: {\n\titems: Array<ChartSeriesDescriptor<K>>;\n}) => ReactNode;\n\nexport type LineChartTooltipRenderer = (props: {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n}) => ReactNode;\n\nexport type LineChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function LineChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Line chart\",\n\tclassName,\n\tshowAxes = false,\n\tshowLegend = false,\n\tcolor,\n\tvalueFormatter,\n\txValueFormatter,\n\tyDomain,\n\tlegend,\n\tcustomTooltip,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: LineChartProps<TData, K>) {\n\tconst lines = applyLeadColor(\n\t\tresolveChartSeries(\n\t\t\tseries,\n\t\t\txyFallbackKeys(data as unknown as Array<{ y2?: number; y3?: number }>) as K[],\n\t\t),\n\t\tcolor,\n\t);\n\tconst resolvedLegend =\n\t\tlegend !== undefined ? (\n\t\t\ttypeof legend === \"function\" ? (\n\t\t\t\tlegend({ items: lines })\n\t\t\t) : (\n\t\t\t\tlegend\n\t\t\t)\n\t\t) : showLegend ? (\n\t\t\t<ChartLegend items={lines} shape=\"line\" />\n\t\t) : undefined;\n\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tlegend={resolvedLegend}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsLine data={data} margin={showAxes ? CHART_PLOT_MARGIN : CHART_PLOT_MARGIN_BARE}>\n\t\t\t\t{showAxes ? <CartesianGrid {...GRID_PROPS} /> : null}\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(!showAxes)} tickFormatter={xValueFormatter} />\n\t\t\t\t<YAxis\n\t\t\t\t\t{...cartesianAxisProps(!showAxes)}\n\t\t\t\t\ttickFormatter={valueFormatter}\n\t\t\t\t\t{...(yDomain ? { domain: yDomain as [number, number] } : {})}\n\t\t\t\t/>\n\t\t\t\t<Tooltip\n\t\t\t\t\t{...chartTooltipProps({\n\t\t\t\t\t\tformatter: valueFormatter,\n\t\t\t\t\t\tcursor: \"line\",\n\t\t\t\t\t\tcustomTooltip,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t{lines.map((item, index) => (\n\t\t\t\t\t<Line\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\ttype=\"monotone\"\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tstroke={seriesColor(item, index)}\n\t\t\t\t\t\tstrokeWidth={CHART_TYPE.strokeWidth}\n\t\t\t\t\t\tdot={false}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsLine>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;;AA0GA,SAAgB,EAGd,EACD,SACA,WACA,eAAY,cACZ,cACA,cAAW,IACX,gBAAa,IACb,UACA,mBACA,oBACA,YACA,WACA,kBACA,YACA,oBACA,yBAC4B;CAC5B,IAAM,IAAQ,EACb,EACC,GACA,EAAe,CAAsD,CACtE,GACA,CACD,GACM,IACL,MAAW,KAAA,IAMP,IACH,kBAAC,GAAD;EAAa,OAAO;EAAO,OAAM;CAAQ,CAAA,IACtC,KAAA,IAPH,OAAO,KAAW,aACjB,EAAO,EAAE,OAAO,EAAM,CAAC,IAEvB;CAMH,OACC,kBAAC,GAAD;EACY;EACA;EACX,QAAQ;EACC;EACQ;EACG;EAEpB,UAAA,kBAAC,GAAD;GAAoB;GAAM,QAAQ,IAAW,IAAoB;GAAjE,UAAA;IACE,IAAW,kBAAC,GAAD,EAAe,GAAI,EAAa,CAAA,IAAI;IAChD,kBAAC,GAAD;KAAO,SAAQ;KAAI,GAAI,EAAmB,CAAC,CAAQ;KAAG,eAAe;IAAkB,CAAA;IACvF,kBAAC,GAAD;KACC,GAAI,EAAmB,CAAC,CAAQ;KAChC,eAAe;KACf,GAAK,IAAU,EAAE,QAAQ,EAA4B,IAAI,CAAC;IAC1D,CAAA;IACD,kBAAC,GAAD,EACC,GAAI,EAAkB;KACrB,WAAW;KACX,QAAQ;KACR;IACD,CAAC,EACD,CAAA;IACA,EAAM,KAAK,GAAM,MACjB,kBAAC,GAAD;KAEC,MAAK;KACL,SAAS,EAAK;KACd,MAAM,EAAK,SAAS,EAAK;KACzB,QAAQ,EAAY,GAAM,CAAK;KAC/B,aAAa,EAAW;KACxB,KAAK;KACL,GAAI;IACJ,GARK,EAAK,GAQV,CACD;GACY;;CACH,CAAA;AAEd"}
1
+ {"version":3,"file":"line.js","names":["RechartsLine","LineChart$1","LineChart","lines","applyLeadColor","resolveChartSeries","series","xyFallbackKeys","data","color","resolvedLegend","legend","showLegend","ChartLegend","ChartShell","showAxes","CHART_PLOT_MARGIN","CHART_PLOT_MARGIN_BARE","CartesianGrid","GRID_PROPS","XAxis","cartesianAxisProps","xValueFormatter","YAxis","valueFormatter","yDomain","Tooltip","chartTooltipProps","Line","item","seriesColor","index","CHART_TYPE","ANIMATION_PROPS"],"sources":["../../src/charts/line.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { CartesianGrid, Line, LineChart as RechartsLine, Tooltip, XAxis, YAxis } from \"recharts\";\nimport {\n\tANIMATION_PROPS,\n\tCHART_PLOT_MARGIN,\n\tCHART_PLOT_MARGIN_BARE,\n\tCHART_TYPE,\n\tcartesianAxisProps,\n\tchartTooltipProps,\n\tGRID_PROPS,\n\tseriesColor,\n} from \"./config\";\nimport { ChartShell } from \"./frame\";\nimport { ChartLegend } from \"./legend\";\nimport {\n\tapplyLeadColor,\n\ttype ChartSeriesDescriptor,\n\tresolveChartSeries,\n\ttype XYPoint,\n\txyFallbackKeys,\n} from \"./series\";\nimport type { ChartTooltipItem } from \"./tooltip\";\n\nexport type LineChartAxisDomain =\n\t| [number | \"auto\" | \"dataMin\", number | \"auto\" | \"dataMax\"]\n\t| readonly [number | \"auto\" | \"dataMin\", number | \"auto\" | \"dataMax\"];\n\nexport type LineChartNumericKeys<T> = {\n\t[K in keyof T]-?: K extends \"x\"\n\t\t? never\n\t\t: [NonNullable<T[K]>] extends [never]\n\t\t\t? never\n\t\t\t: NonNullable<T[K]> extends number\n\t\t\t\t? K extends string\n\t\t\t\t\t? K\n\t\t\t\t\t: never\n\t\t\t\t: never;\n}[keyof T];\n\nexport type LineChartLegendRenderer<K extends string = string> = (props: {\n\titems: Array<ChartSeriesDescriptor<K>>;\n}) => ReactNode;\n\nexport type LineChartTooltipRenderer = (props: {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n}) => ReactNode;\n\nexport type LineChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function LineChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Line chart\",\n\tclassName,\n\tshowAxes = false,\n\tshowLegend = false,\n\tcolor,\n\tvalueFormatter,\n\txValueFormatter,\n\tyDomain,\n\tlegend,\n\tcustomTooltip,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: LineChartProps<TData, K>) {\n\tconst lines = applyLeadColor(\n\t\tresolveChartSeries(\n\t\t\tseries,\n\t\t\txyFallbackKeys(data as unknown as Array<{ y2?: number; y3?: number }>) as K[],\n\t\t),\n\t\tcolor,\n\t);\n\tconst resolvedLegend =\n\t\tlegend !== undefined ? (\n\t\t\ttypeof legend === \"function\" ? (\n\t\t\t\tlegend({ items: lines })\n\t\t\t) : (\n\t\t\t\tlegend\n\t\t\t)\n\t\t) : showLegend ? (\n\t\t\t<ChartLegend items={lines} shape=\"line\" />\n\t\t) : undefined;\n\n\treturn (\n\t\t<ChartShell\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tlegend={resolvedLegend}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsLine data={data} margin={showAxes ? CHART_PLOT_MARGIN : CHART_PLOT_MARGIN_BARE}>\n\t\t\t\t{showAxes ? <CartesianGrid {...GRID_PROPS} /> : null}\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(!showAxes)} tickFormatter={xValueFormatter} />\n\t\t\t\t<YAxis\n\t\t\t\t\t{...cartesianAxisProps(!showAxes)}\n\t\t\t\t\ttickFormatter={valueFormatter}\n\t\t\t\t\t{...(yDomain ? { domain: yDomain as [number, number] } : {})}\n\t\t\t\t/>\n\t\t\t\t<Tooltip\n\t\t\t\t\t{...chartTooltipProps({\n\t\t\t\t\t\tformatter: valueFormatter,\n\t\t\t\t\t\tcursor: \"line\",\n\t\t\t\t\t\tcustomTooltip,\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t\t{lines.map((item, index) => (\n\t\t\t\t\t<Line\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\ttype=\"monotone\"\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tstroke={seriesColor(item, index)}\n\t\t\t\t\t\tstrokeWidth={CHART_TYPE.strokeWidth}\n\t\t\t\t\t\tdot={false}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsLine>\n\t\t</ChartShell>\n\t);\n}\n"],"mappings":";;;;;;;;AA0GA,SAAgBE,EAGd,EACD,SACA,WACA,eAAY,cACZ,cACA,cAAW,IACX,gBAAa,IACb,UACA,mBACA,oBACA,YACA,WACA,kBACA,YACA,oBACA,yBAC4B;CAC5B,IAAMC,IAAQC,EACbC,EACCC,GACAC,EAAeC,CAAsD,CACtE,GACAC,CACD,GACMC,IACLC,MAAW,KAAA,IAMPC,IACH,kBAACC,GAAD;EAAa,OAAOV;EAAO,OAAM;CAAQ,CAAA,IACtC,KAAA,IAPH,OAAOQ,KAAW,aACjBA,EAAO,EAAE,OAAOR,EAAM,CAAC,IAEvBQ;CAMH,OACC,kBAACG,GAAD;EACY;EACA;EACX,QAAQJ;EACC;EACQ;EACG;EAEpB,UAAA,kBAACV,GAAD;GAAoB;GAAM,QAAQe,IAAWC,IAAoBC;GAAjE,UAAA;IACEF,IAAW,kBAACG,GAAD,EAAe,GAAIC,EAAa,CAAA,IAAI;IAChD,kBAACC,GAAD;KAAO,SAAQ;KAAI,GAAIC,EAAmB,CAACN,CAAQ;KAAG,eAAeO;IAAkB,CAAA;IACvF,kBAACC,GAAD;KACC,GAAIF,EAAmB,CAACN,CAAQ;KAChC,eAAeS;KACf,GAAKC,IAAU,EAAE,QAAQA,EAA4B,IAAI,CAAC;IAC1D,CAAA;IACD,kBAACC,GAAD,EACC,GAAIC,EAAkB;KACrB,WAAWH;KACX,QAAQ;KACR;IACD,CAAC,EACD,CAAA;IACArB,EAAM,KAAK,GAAM,MACjB,kBAACyB,GAAD;KAEC,MAAK;KACL,SAASC,EAAK;KACd,MAAMA,EAAK,SAASA,EAAK;KACzB,QAAQC,EAAYD,GAAME,CAAK;KAC/B,aAAaC,EAAW;KACxB,KAAK;KACL,GAAIC;IACJ,GARKJ,EAAK,GAQV,CACD;GACY;;CACH,CAAA;AAEd"}
@@ -35,11 +35,11 @@ var t = (e) => `hsl(var(--basalt-${e}))`, n = (e, t) => `hsl(var(--basalt-${e})
35
35
  ];
36
36
  function s({ ariaLabel: t = "Chart colors" }) {
37
37
  return /* @__PURE__ */ e("div", {
38
- className: "flex flex-wrap gap-2",
38
+ className: "flex flex-wrap gap-basalt-space-lg",
39
39
  role: "img",
40
40
  "aria-label": t,
41
41
  children: o.map((t) => /* @__PURE__ */ e("span", {
42
- className: "h-8 w-8 rounded-basalt-sm",
42
+ className: "h-basalt-8 w-basalt-8 rounded-basalt-sm",
43
43
  style: { background: t }
44
44
  }, t))
45
45
  });
@@ -1 +1 @@
1
- {"version":3,"file":"palette.js","names":[],"sources":["../../src/charts/palette.tsx"],"sourcesContent":["const v = (token: string) => `hsl(var(--basalt-${token}))`;\n\nexport const withAlpha = (token: string, alpha: number) => `hsl(var(--basalt-${token}) / ${alpha})`;\n\nexport const chartAxis = v(\"chart-axis\");\nexport const chartMuted = v(\"chart-muted\");\n\nexport const chart = {\n\tprimary: v(\"chart-1\"),\n\tsky: v(\"chart-2\"),\n\tteal: v(\"chart-3\"),\n\tjade: v(\"chart-4\"),\n\tgreen: v(\"chart-5\"),\n\tlime: v(\"chart-6\"),\n\tamber: v(\"chart-7\"),\n\torange: v(\"chart-8\"),\n\tvermilion: v(\"chart-9\"),\n\tred: v(\"chart-10\"),\n\trose: v(\"chart-11\"),\n\tmagenta: v(\"chart-12\"),\n\torchid: v(\"chart-13\"),\n\tpurple: v(\"chart-14\"),\n\tindigo: v(\"chart-15\"),\n\tcobalt: v(\"chart-16\"),\n\tsteel: v(\"chart-17\"),\n\tcadet: v(\"chart-18\"),\n\tseafoam: v(\"chart-19\"),\n\tolive: v(\"chart-20\"),\n\tgold: v(\"chart-21\"),\n\ttangerine: v(\"chart-22\"),\n\tcrimson: v(\"chart-23\"),\n\tgray: v(\"chart-24\"),\n} as const;\n\n/** Fixed five-color series cycle; independent of the application accent. */\nexport const CHART_COLORS = [chart.primary, chart.rose, chart.green, chart.amber, chart.gray];\n\nexport type ChartPaletteProps = {\n\tariaLabel?: string;\n};\n\nexport function ChartPalette({ ariaLabel = \"Chart colors\" }: ChartPaletteProps) {\n\treturn (\n\t\t<div className=\"flex flex-wrap gap-2\" role=\"img\" aria-label={ariaLabel}>\n\t\t\t{CHART_COLORS.map((color) => (\n\t\t\t\t<span key={color} className=\"h-8 w-8 rounded-basalt-sm\" style={{ background: color }} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;AAAA,IAAM,KAAK,MAAkB,oBAAoB,EAAM,KAE1C,KAAa,GAAe,MAAkB,oBAAoB,EAAM,MAAM,EAAM,IAEpF,IAAY,EAAE,YAAY,GAC1B,IAAa,EAAE,aAAa,GAE5B,IAAQ;CACpB,SAAS,EAAE,SAAS;CACpB,KAAK,EAAE,SAAS;CAChB,MAAM,EAAE,SAAS;CACjB,MAAM,EAAE,SAAS;CACjB,OAAO,EAAE,SAAS;CAClB,MAAM,EAAE,SAAS;CACjB,OAAO,EAAE,SAAS;CAClB,QAAQ,EAAE,SAAS;CACnB,WAAW,EAAE,SAAS;CACtB,KAAK,EAAE,UAAU;CACjB,MAAM,EAAE,UAAU;CAClB,SAAS,EAAE,UAAU;CACrB,QAAQ,EAAE,UAAU;CACpB,QAAQ,EAAE,UAAU;CACpB,QAAQ,EAAE,UAAU;CACpB,QAAQ,EAAE,UAAU;CACpB,OAAO,EAAE,UAAU;CACnB,OAAO,EAAE,UAAU;CACnB,SAAS,EAAE,UAAU;CACrB,OAAO,EAAE,UAAU;CACnB,MAAM,EAAE,UAAU;CAClB,WAAW,EAAE,UAAU;CACvB,SAAS,EAAE,UAAU;CACrB,MAAM,EAAE,UAAU;AACnB,GAGa,IAAe;CAAC,EAAM;CAAS,EAAM;CAAM,EAAM;CAAO,EAAM;CAAO,EAAM;AAAI;AAM5F,SAAgB,EAAa,EAAE,eAAY,kBAAqC;CAC/E,OACC,kBAAC,OAAD;EAAK,WAAU;EAAuB,MAAK;EAAM,cAAY;EAC3D,UAAA,EAAa,KAAK,MAClB,kBAAC,QAAD;GAAkB,WAAU;GAA4B,OAAO,EAAE,YAAY,EAAM;EAAI,GAA5E,CAA4E,CACvF;CACG,CAAA;AAEP"}
1
+ {"version":3,"file":"palette.js","names":["v","token","withAlpha","alpha","chartAxis","chartMuted","chart","CHART_COLORS","ChartPalette","ariaLabel","color"],"sources":["../../src/charts/palette.tsx"],"sourcesContent":["const v = (token: string) => `hsl(var(--basalt-${token}))`;\n\nexport const withAlpha = (token: string, alpha: number) => `hsl(var(--basalt-${token}) / ${alpha})`;\n\nexport const chartAxis = v(\"chart-axis\");\nexport const chartMuted = v(\"chart-muted\");\n\nexport const chart = {\n\tprimary: v(\"chart-1\"),\n\tsky: v(\"chart-2\"),\n\tteal: v(\"chart-3\"),\n\tjade: v(\"chart-4\"),\n\tgreen: v(\"chart-5\"),\n\tlime: v(\"chart-6\"),\n\tamber: v(\"chart-7\"),\n\torange: v(\"chart-8\"),\n\tvermilion: v(\"chart-9\"),\n\tred: v(\"chart-10\"),\n\trose: v(\"chart-11\"),\n\tmagenta: v(\"chart-12\"),\n\torchid: v(\"chart-13\"),\n\tpurple: v(\"chart-14\"),\n\tindigo: v(\"chart-15\"),\n\tcobalt: v(\"chart-16\"),\n\tsteel: v(\"chart-17\"),\n\tcadet: v(\"chart-18\"),\n\tseafoam: v(\"chart-19\"),\n\tolive: v(\"chart-20\"),\n\tgold: v(\"chart-21\"),\n\ttangerine: v(\"chart-22\"),\n\tcrimson: v(\"chart-23\"),\n\tgray: v(\"chart-24\"),\n} as const;\n\n/** Fixed five-color series cycle; independent of the application accent. */\nexport const CHART_COLORS = [chart.primary, chart.rose, chart.green, chart.amber, chart.gray];\n\nexport type ChartPaletteProps = {\n\tariaLabel?: string;\n};\n\nexport function ChartPalette({ ariaLabel = \"Chart colors\" }: ChartPaletteProps) {\n\treturn (\n\t\t<div className=\"flex flex-wrap gap-basalt-space-lg\" role=\"img\" aria-label={ariaLabel}>\n\t\t\t{CHART_COLORS.map((color) => (\n\t\t\t\t<span\n\t\t\t\t\tkey={color}\n\t\t\t\t\tclassName=\"h-basalt-8 w-basalt-8 rounded-basalt-sm\"\n\t\t\t\t\tstyle={{ background: color }}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;AAAA,IAAMA,KAAK,MAAkB,oBAAoBC,EAAM,KAE1CC,KAAa,GAAe,MAAkB,oBAAoBD,EAAM,MAAME,EAAM,IAEpFC,IAAYJ,EAAE,YAAY,GAC1BK,IAAaL,EAAE,aAAa,GAE5BM,IAAQ;CACpB,SAASN,EAAE,SAAS;CACpB,KAAKA,EAAE,SAAS;CAChB,MAAMA,EAAE,SAAS;CACjB,MAAMA,EAAE,SAAS;CACjB,OAAOA,EAAE,SAAS;CAClB,MAAMA,EAAE,SAAS;CACjB,OAAOA,EAAE,SAAS;CAClB,QAAQA,EAAE,SAAS;CACnB,WAAWA,EAAE,SAAS;CACtB,KAAKA,EAAE,UAAU;CACjB,MAAMA,EAAE,UAAU;CAClB,SAASA,EAAE,UAAU;CACrB,QAAQA,EAAE,UAAU;CACpB,QAAQA,EAAE,UAAU;CACpB,QAAQA,EAAE,UAAU;CACpB,QAAQA,EAAE,UAAU;CACpB,OAAOA,EAAE,UAAU;CACnB,OAAOA,EAAE,UAAU;CACnB,SAASA,EAAE,UAAU;CACrB,OAAOA,EAAE,UAAU;CACnB,MAAMA,EAAE,UAAU;CAClB,WAAWA,EAAE,UAAU;CACvB,SAASA,EAAE,UAAU;CACrB,MAAMA,EAAE,UAAU;AACnB,GAGaO,IAAe;CAACD,EAAM;CAASA,EAAM;CAAMA,EAAM;CAAOA,EAAM;CAAOA,EAAM;AAAI;AAM5F,SAAgBE,EAAa,EAAE,eAAY,kBAAqC;CAC/E,OACC,kBAAC,OAAD;EAAK,WAAU;EAAqC,MAAK;EAAM,cAAYC;EACzE,UAAAF,EAAa,KAAK,MAClB,kBAAC,QAAD;GAEC,WAAU;GACV,OAAO,EAAE,YAAYG,EAAM;EAC3B,GAHKA,CAGL,CACD;CACG,CAAA;AAEP"}
@@ -1 +1 @@
1
- {"version":3,"file":"radar.js","names":[],"sources":["../../src/charts/radar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { PolarAngleAxis, PolarGrid, Radar, RadarChart as RechartsRadar } from \"recharts\";\nimport { ANIMATION_PROPS, CHART_TYPE, chartTickStyle, GRID_PROPS, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { ChartSeriesDescriptor, RadarPoint } from \"./series\";\n\nexport type RadarChartProps = {\n\tdata: RadarPoint[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function RadarChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Radar chart\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: RadarChartProps) {\n\tconst fill = seriesColor(series?.[0], 3);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsRadar data={data} outerRadius={60}>\n\t\t\t\t<PolarGrid stroke={GRID_PROPS.stroke} strokeOpacity={GRID_PROPS.strokeOpacity} />\n\t\t\t\t<PolarAngleAxis dataKey=\"subject\" tick={chartTickStyle()} tickLine={false} />\n\t\t\t\t<Radar\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tname={series?.[0]?.label}\n\t\t\t\t\tfill={fill}\n\t\t\t\t\tfillOpacity={0.3}\n\t\t\t\t\tstroke={fill}\n\t\t\t\t\tstrokeWidth={CHART_TYPE.strokeWidth}\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t/>\n\t\t\t</RechartsRadar>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;AA6BA,SAAgB,EAAW,EAC1B,SACA,WACA,eAAY,eACZ,cACA,YACA,oBACA,yBACmB;CACnB,IAAM,IAAO,EAAY,IAAS,IAAI,CAAC;CACvC,OACC,kBAAC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAAC,GAAD;GAAqB;GAAM,aAAa;GAAxC,UAAA;IACC,kBAAC,GAAD;KAAW,QAAQ,EAAW;KAAQ,eAAe,EAAW;IAAgB,CAAA;IAChF,kBAAC,GAAD;KAAgB,SAAQ;KAAU,MAAM,EAAe;KAAG,UAAU;IAAQ,CAAA;IAC5E,kBAAC,GAAD;KACC,SAAQ;KACR,MAAM,IAAS,EAAE,EAAE;KACb;KACN,aAAa;KACb,QAAQ;KACR,aAAa,EAAW;KACxB,GAAI;IACJ,CAAA;GACa;;CACJ,CAAA;AAEd"}
1
+ {"version":3,"file":"radar.js","names":["RechartsRadar","RadarChart$1","RadarChart","fill","seriesColor","series","ChartFrame","PolarGrid","GRID_PROPS","PolarAngleAxis","chartTickStyle","Radar","CHART_TYPE","ANIMATION_PROPS"],"sources":["../../src/charts/radar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { PolarAngleAxis, PolarGrid, Radar, RadarChart as RechartsRadar } from \"recharts\";\nimport { ANIMATION_PROPS, CHART_TYPE, chartTickStyle, GRID_PROPS, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { ChartSeriesDescriptor, RadarPoint } from \"./series\";\n\nexport type RadarChartProps = {\n\tdata: RadarPoint[];\n\tseries?: ChartSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function RadarChart({\n\tdata,\n\tseries,\n\tariaLabel = \"Radar chart\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: RadarChartProps) {\n\tconst fill = seriesColor(series?.[0], 3);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsRadar data={data} outerRadius={60}>\n\t\t\t\t<PolarGrid stroke={GRID_PROPS.stroke} strokeOpacity={GRID_PROPS.strokeOpacity} />\n\t\t\t\t<PolarAngleAxis dataKey=\"subject\" tick={chartTickStyle()} tickLine={false} />\n\t\t\t\t<Radar\n\t\t\t\t\tdataKey=\"value\"\n\t\t\t\t\tname={series?.[0]?.label}\n\t\t\t\t\tfill={fill}\n\t\t\t\t\tfillOpacity={0.3}\n\t\t\t\t\tstroke={fill}\n\t\t\t\t\tstrokeWidth={CHART_TYPE.strokeWidth}\n\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t/>\n\t\t\t</RechartsRadar>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;AA6BA,SAAgBE,EAAW,EAC1B,SACA,WACA,eAAY,eACZ,cACA,YACA,oBACA,yBACmB;CACnB,IAAMC,IAAOC,EAAYC,IAAS,IAAI,CAAC;CACvC,OACC,kBAACC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAACN,GAAD;GAAqB;GAAM,aAAa;GAAxC,UAAA;IACC,kBAACO,GAAD;KAAW,QAAQC,EAAW;KAAQ,eAAeA,EAAW;IAAgB,CAAA;IAChF,kBAACC,GAAD;KAAgB,SAAQ;KAAU,MAAMC,EAAe;KAAG,UAAU;IAAQ,CAAA;IAC5E,kBAACC,GAAD;KACC,SAAQ;KACR,MAAMN,IAAS,EAAE,EAAE;KACb;KACN,aAAa;KACb,QAAQF;KACR,aAAaS,EAAW;KACxB,GAAIC;IACJ,CAAA;GACa;;CACJ,CAAA;AAEd"}
@@ -1 +1 @@
1
- {"version":3,"file":"sample.js","names":[],"sources":["../../src/charts/sample.ts"],"sourcesContent":["import type { BulletPoint, NamedValue, RadarPoint, SankeyData, XYPoint } from \"./series\";\n\nexport type { BulletPoint, NamedValue, RadarPoint, SankeyData, XYPoint } from \"./series\";\n\nexport const SAMPLE: XYPoint[] = [\n\t{ x: \"Mon\", y: 12, y2: 8 },\n\t{ x: \"Tue\", y: 18, y2: 11 },\n\t{ x: \"Wed\", y: 9, y2: 14 },\n\t{ x: \"Thu\", y: 22, y2: 16 },\n\t{ x: \"Fri\", y: 15, y2: 10 },\n];\n\nexport const DONUT_SAMPLE: NamedValue[] = [\n\t{ name: \"A\", value: 40 },\n\t{ name: \"B\", value: 25 },\n\t{ name: \"C\", value: 35 },\n];\n\nexport const RADAR_SAMPLE: RadarPoint[] = [\n\t{ subject: \"Speed\", value: 80 },\n\t{ subject: \"Quality\", value: 92 },\n\t{ subject: \"Coverage\", value: 76 },\n\t{ subject: \"Reliability\", value: 88 },\n\t{ subject: \"Support\", value: 70 },\n];\n\nexport const FUNNEL_SAMPLE: NamedValue[] = [\n\t{ name: \"Visits\", value: 2400 },\n\t{ name: \"Signup\", value: 820 },\n\t{ name: \"Activate\", value: 420 },\n\t{ name: \"Upgrade\", value: 180 },\n];\n\nexport const BULLET_SAMPLE: BulletPoint[] = [\n\t{ name: \"Revenue\", value: 68, target: 80 },\n\t{ name: \"Retention\", value: 72, target: 85 },\n\t{ name: \"Adoption\", value: 58, target: 70 },\n];\n\nexport const SANKEY_SAMPLE: SankeyData = {\n\tnodes: [{ name: \"Visits\" }, { name: \"Signup\" }, { name: \"Activate\" }, { name: \"Upgrade\" }],\n\tlinks: [\n\t\t{ source: 0, target: 1, value: 1200 },\n\t\t{ source: 1, target: 2, value: 620 },\n\t\t{ source: 2, target: 3, value: 240 },\n\t],\n};\n"],"mappings":";;AAIA,IAAa,IAAoB;CAChC;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAE;CACzB;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;CAC1B;EAAE,GAAG;EAAO,GAAG;EAAG,IAAI;CAAG;CACzB;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;CAC1B;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;AAC3B,GAEa,IAA6B;CACzC;EAAE,MAAM;EAAK,OAAO;CAAG;CACvB;EAAE,MAAM;EAAK,OAAO;CAAG;CACvB;EAAE,MAAM;EAAK,OAAO;CAAG;AACxB,GAEa,IAA6B;CACzC;EAAE,SAAS;EAAS,OAAO;CAAG;CAC9B;EAAE,SAAS;EAAW,OAAO;CAAG;CAChC;EAAE,SAAS;EAAY,OAAO;CAAG;CACjC;EAAE,SAAS;EAAe,OAAO;CAAG;CACpC;EAAE,SAAS;EAAW,OAAO;CAAG;AACjC,GAEa,IAA8B;CAC1C;EAAE,MAAM;EAAU,OAAO;CAAK;CAC9B;EAAE,MAAM;EAAU,OAAO;CAAI;CAC7B;EAAE,MAAM;EAAY,OAAO;CAAI;CAC/B;EAAE,MAAM;EAAW,OAAO;CAAI;AAC/B,GAEa,IAA+B;CAC3C;EAAE,MAAM;EAAW,OAAO;EAAI,QAAQ;CAAG;CACzC;EAAE,MAAM;EAAa,OAAO;EAAI,QAAQ;CAAG;CAC3C;EAAE,MAAM;EAAY,OAAO;EAAI,QAAQ;CAAG;AAC3C,GAEa,IAA4B;CACxC,OAAO;EAAC,EAAE,MAAM,SAAS;EAAG,EAAE,MAAM,SAAS;EAAG,EAAE,MAAM,WAAW;EAAG,EAAE,MAAM,UAAU;CAAC;CACzF,OAAO;EACN;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAK;EACpC;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAI;EACnC;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAI;CACpC;AACD"}
1
+ {"version":3,"file":"sample.js","names":["SAMPLE","DONUT_SAMPLE","RADAR_SAMPLE","FUNNEL_SAMPLE","BULLET_SAMPLE","SANKEY_SAMPLE"],"sources":["../../src/charts/sample.ts"],"sourcesContent":["import type { BulletPoint, NamedValue, RadarPoint, SankeyData, XYPoint } from \"./series\";\n\nexport type { BulletPoint, NamedValue, RadarPoint, SankeyData, XYPoint } from \"./series\";\n\nexport const SAMPLE: XYPoint[] = [\n\t{ x: \"Mon\", y: 12, y2: 8 },\n\t{ x: \"Tue\", y: 18, y2: 11 },\n\t{ x: \"Wed\", y: 9, y2: 14 },\n\t{ x: \"Thu\", y: 22, y2: 16 },\n\t{ x: \"Fri\", y: 15, y2: 10 },\n];\n\nexport const DONUT_SAMPLE: NamedValue[] = [\n\t{ name: \"A\", value: 40 },\n\t{ name: \"B\", value: 25 },\n\t{ name: \"C\", value: 35 },\n];\n\nexport const RADAR_SAMPLE: RadarPoint[] = [\n\t{ subject: \"Speed\", value: 80 },\n\t{ subject: \"Quality\", value: 92 },\n\t{ subject: \"Coverage\", value: 76 },\n\t{ subject: \"Reliability\", value: 88 },\n\t{ subject: \"Support\", value: 70 },\n];\n\nexport const FUNNEL_SAMPLE: NamedValue[] = [\n\t{ name: \"Visits\", value: 2400 },\n\t{ name: \"Signup\", value: 820 },\n\t{ name: \"Activate\", value: 420 },\n\t{ name: \"Upgrade\", value: 180 },\n];\n\nexport const BULLET_SAMPLE: BulletPoint[] = [\n\t{ name: \"Revenue\", value: 68, target: 80 },\n\t{ name: \"Retention\", value: 72, target: 85 },\n\t{ name: \"Adoption\", value: 58, target: 70 },\n];\n\nexport const SANKEY_SAMPLE: SankeyData = {\n\tnodes: [{ name: \"Visits\" }, { name: \"Signup\" }, { name: \"Activate\" }, { name: \"Upgrade\" }],\n\tlinks: [\n\t\t{ source: 0, target: 1, value: 1200 },\n\t\t{ source: 1, target: 2, value: 620 },\n\t\t{ source: 2, target: 3, value: 240 },\n\t],\n};\n"],"mappings":";;AAIA,IAAaA,IAAoB;CAChC;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAE;CACzB;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;CAC1B;EAAE,GAAG;EAAO,GAAG;EAAG,IAAI;CAAG;CACzB;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;CAC1B;EAAE,GAAG;EAAO,GAAG;EAAI,IAAI;CAAG;AAC3B,GAEaC,IAA6B;CACzC;EAAE,MAAM;EAAK,OAAO;CAAG;CACvB;EAAE,MAAM;EAAK,OAAO;CAAG;CACvB;EAAE,MAAM;EAAK,OAAO;CAAG;AACxB,GAEaC,IAA6B;CACzC;EAAE,SAAS;EAAS,OAAO;CAAG;CAC9B;EAAE,SAAS;EAAW,OAAO;CAAG;CAChC;EAAE,SAAS;EAAY,OAAO;CAAG;CACjC;EAAE,SAAS;EAAe,OAAO;CAAG;CACpC;EAAE,SAAS;EAAW,OAAO;CAAG;AACjC,GAEaC,IAA8B;CAC1C;EAAE,MAAM;EAAU,OAAO;CAAK;CAC9B;EAAE,MAAM;EAAU,OAAO;CAAI;CAC7B;EAAE,MAAM;EAAY,OAAO;CAAI;CAC/B;EAAE,MAAM;EAAW,OAAO;CAAI;AAC/B,GAEaC,IAA+B;CAC3C;EAAE,MAAM;EAAW,OAAO;EAAI,QAAQ;CAAG;CACzC;EAAE,MAAM;EAAa,OAAO;EAAI,QAAQ;CAAG;CAC3C;EAAE,MAAM;EAAY,OAAO;EAAI,QAAQ;CAAG;AAC3C,GAEaC,IAA4B;CACxC,OAAO;EAAC,EAAE,MAAM,SAAS;EAAG,EAAE,MAAM,SAAS;EAAG,EAAE,MAAM,WAAW;EAAG,EAAE,MAAM,UAAU;CAAC;CACzF,OAAO;EACN;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAK;EACpC;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAI;EACnC;GAAE,QAAQ;GAAG,QAAQ;GAAG,OAAO;EAAI;CACpC;AACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"sankey.js","names":[],"sources":["../../src/charts/sankey.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Sankey, type SankeyNodeProps, Tooltip } from \"recharts\";\nimport { chartFontSize, chartTooltipProps } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { CHART_COLORS, chartAxis } from \"./palette\";\nimport type { SankeyData } from \"./series\";\n\nfunction SankeyNode({ x, y, width, height, payload }: SankeyNodeProps) {\n\treturn (\n\t\t<g>\n\t\t\t<rect x={x} y={y} width={width} height={height} fill={CHART_COLORS[2]} />\n\t\t\t<text\n\t\t\t\tx={x + width + 6}\n\t\t\t\ty={y + height / 2}\n\t\t\t\tdominantBaseline=\"middle\"\n\t\t\t\tfontSize={chartFontSize(\"axis\")}\n\t\t\t\tfill={chartAxis}\n\t\t\t>\n\t\t\t\t{payload.name}\n\t\t\t</text>\n\t\t</g>\n\t);\n}\n\nexport type SankeyChartProps = {\n\tdata: SankeyData;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function SankeyChart({\n\tdata,\n\tariaLabel = \"Sankey chart\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: SankeyChartProps) {\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<Sankey\n\t\t\t\tdata={data}\n\t\t\t\tnodePadding={16}\n\t\t\t\tnodeWidth={12}\n\t\t\t\tmargin={{ top: 8, right: 72, bottom: 8, left: 8 }}\n\t\t\t\tnode={SankeyNode}\n\t\t\t\tlink={{ stroke: CHART_COLORS[0], strokeOpacity: 0.3 }}\n\t\t\t>\n\t\t\t\t<Tooltip {...chartTooltipProps({ cursor: false })} />\n\t\t\t</Sankey>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AAOA,SAAS,EAAW,EAAE,MAAG,MAAG,UAAO,WAAQ,cAA4B;CACtE,OACC,kBAAC,KAAD,EAAA,UAAA,CACC,kBAAC,QAAD;EAAS;EAAM;EAAU;EAAe;EAAQ,MAAM,EAAa;CAAK,CAAA,GACxE,kBAAC,QAAD;EACC,GAAG,IAAI,IAAQ;EACf,GAAG,IAAI,IAAS;EAChB,kBAAiB;EACjB,UAAU,EAAc,MAAM;EAC9B,MAAM;EAEL,UAAA,EAAQ;CACJ,CAAA,CACJ,EAAA,CAAA;AAEL;AAwBA,SAAgB,EAAY,EAC3B,SACA,eAAY,gBACZ,cACA,YACA,oBACA,yBACoB;CACpB,OACC,kBAAC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAAC,GAAD;GACO;GACN,aAAa;GACb,WAAW;GACX,QAAQ;IAAE,KAAK;IAAG,OAAO;IAAI,QAAQ;IAAG,MAAM;GAAE;GAChD,MAAM;GACN,MAAM;IAAE,QAAQ,EAAa;IAAI,eAAe;GAAI;GAEpD,UAAA,kBAAC,GAAD,EAAS,GAAI,EAAkB,EAAE,QAAQ,GAAM,CAAC,EAAI,CAAA;EAC7C,CAAA;CACG,CAAA;AAEd"}
1
+ {"version":3,"file":"sankey.js","names":["SankeyNode","CHART_COLORS","x","width","y","height","chartFontSize","chartAxis","payload","SankeyChart","ChartFrame","Sankey","Tooltip","chartTooltipProps"],"sources":["../../src/charts/sankey.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Sankey, type SankeyNodeProps, Tooltip } from \"recharts\";\nimport { chartFontSize, chartTooltipProps } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport { CHART_COLORS, chartAxis } from \"./palette\";\nimport type { SankeyData } from \"./series\";\n\nfunction SankeyNode({ x, y, width, height, payload }: SankeyNodeProps) {\n\treturn (\n\t\t<g>\n\t\t\t<rect x={x} y={y} width={width} height={height} fill={CHART_COLORS[2]} />\n\t\t\t<text\n\t\t\t\tx={x + width + 6}\n\t\t\t\ty={y + height / 2}\n\t\t\t\tdominantBaseline=\"middle\"\n\t\t\t\tfontSize={chartFontSize(\"axis\")}\n\t\t\t\tfill={chartAxis}\n\t\t\t>\n\t\t\t\t{payload.name}\n\t\t\t</text>\n\t\t</g>\n\t);\n}\n\nexport type SankeyChartProps = {\n\tdata: SankeyData;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function SankeyChart({\n\tdata,\n\tariaLabel = \"Sankey chart\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: SankeyChartProps) {\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<Sankey\n\t\t\t\tdata={data}\n\t\t\t\tnodePadding={16}\n\t\t\t\tnodeWidth={12}\n\t\t\t\tmargin={{ top: 8, right: 72, bottom: 8, left: 8 }}\n\t\t\t\tnode={SankeyNode}\n\t\t\t\tlink={{ stroke: CHART_COLORS[0], strokeOpacity: 0.3 }}\n\t\t\t>\n\t\t\t\t<Tooltip {...chartTooltipProps({ cursor: false })} />\n\t\t\t</Sankey>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AAOA,SAASA,EAAW,EAAE,MAAG,MAAG,UAAO,WAAQ,cAA4B;CACtE,OACC,kBAAC,KAAD,EAAA,UAAA,CACC,kBAAC,QAAD;EAAS;EAAM;EAAU;EAAe;EAAQ,MAAMC,EAAa;CAAK,CAAA,GACxE,kBAAC,QAAD;EACC,GAAGC,IAAIC,IAAQ;EACf,GAAGC,IAAIC,IAAS;EAChB,kBAAiB;EACjB,UAAUC,EAAc,MAAM;EAC9B,MAAMC;EAEL,UAAAC,EAAQ;CACJ,CAAA,CACJ,EAAA,CAAA;AAEL;AAwBA,SAAgBC,EAAY,EAC3B,SACA,eAAY,gBACZ,cACA,YACA,oBACA,yBACoB;CACpB,OACC,kBAACC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAACC,GAAD;GACO;GACN,aAAa;GACb,WAAW;GACX,QAAQ;IAAE,KAAK;IAAG,OAAO;IAAI,QAAQ;IAAG,MAAM;GAAE;GAChD,MAAMX;GACN,MAAM;IAAE,QAAQC,EAAa;IAAI,eAAe;GAAI;GAEpD,UAAA,kBAACW,GAAD,EAAS,GAAIC,EAAkB,EAAE,QAAQ,GAAM,CAAC,EAAI,CAAA;EAC7C,CAAA;CACG,CAAA;AAEd"}
@@ -1 +1 @@
1
- {"version":3,"file":"series.js","names":[],"sources":["../../src/charts/series.ts"],"sourcesContent":["export type ChartSeriesDescriptor<K extends string = string> = {\n\tkey: K;\n\tlabel?: string;\n\tcolor?: string;\n};\n\nexport type XYSeriesKey = \"y\" | \"y2\" | \"y3\";\nexport type XYSeriesDescriptor<K extends string = XYSeriesKey> = ChartSeriesDescriptor<K>;\nexport type BulletSeriesKey = \"value\" | \"target\";\nexport type BulletSeriesDescriptor = ChartSeriesDescriptor & { key: BulletSeriesKey };\n\nexport type XYPoint = { x: string | number; y: number; y2?: number; y3?: number };\nexport type NamedValue = { name: string; value: number };\nexport type RadarPoint = { subject: string; value: number };\nexport type BulletPoint = { name: string; value: number; target: number };\nexport type SankeyData = {\n\tnodes: { name: string }[];\n\tlinks: { source: number; target: number; value: number }[];\n};\n\nexport function resolveChartSeries<K extends string = string>(\n\tseries: Array<ChartSeriesDescriptor<K>> | undefined,\n\tfallbackKeys: K[],\n): Array<ChartSeriesDescriptor<K>> {\n\tif (series && series.length > 0) {\n\t\treturn series;\n\t}\n\treturn fallbackKeys.map((key) => ({ key }));\n}\n\nexport function applyLeadColor<K extends string = string>(\n\titems: Array<ChartSeriesDescriptor<K>>,\n\tcolor?: string,\n): Array<ChartSeriesDescriptor<K>> {\n\tif (!color) {\n\t\treturn items;\n\t}\n\treturn items.map((item, index) => (index === 0 ? { ...item, color: item.color ?? color } : item));\n}\n\nexport function xyFallbackKeys(data: Array<{ y2?: number; y3?: number }>): string[] {\n\tconst keys = [\"y\"];\n\tif (data.some((point) => point.y2 != null)) {\n\t\tkeys.push(\"y2\");\n\t}\n\tif (data.some((point) => point.y3 != null)) {\n\t\tkeys.push(\"y3\");\n\t}\n\treturn keys;\n}\n"],"mappings":";;AAoBA,SAAgB,EACf,GACA,GACkC;CAIlC,OAHI,KAAU,EAAO,SAAS,IACtB,IAED,EAAa,KAAK,OAAS,EAAE,OAAI,EAAE;AAC3C;AAEA,SAAgB,EACf,GACA,GACkC;CAIlC,OAHK,IAGE,EAAM,KAAK,GAAM,MAAW,MAAU,IAAI;EAAE,GAAG;EAAM,OAAO,EAAK,SAAS;CAAM,IAAI,CAAK,IAFxF;AAGT;AAEA,SAAgB,EAAe,GAAqD;CACnF,IAAM,IAAO,CAAC,GAAG;CAOjB,OANI,EAAK,MAAM,MAAU,EAAM,MAAM,IAAI,KACxC,EAAK,KAAK,IAAI,GAEX,EAAK,MAAM,MAAU,EAAM,MAAM,IAAI,KACxC,EAAK,KAAK,IAAI,GAER;AACR"}
1
+ {"version":3,"file":"series.js","names":["resolveChartSeries","series","fallbackKeys","applyLeadColor","color","items","index","item","xyFallbackKeys","keys","data","point"],"sources":["../../src/charts/series.ts"],"sourcesContent":["export type ChartSeriesDescriptor<K extends string = string> = {\n\tkey: K;\n\tlabel?: string;\n\tcolor?: string;\n};\n\nexport type XYSeriesKey = \"y\" | \"y2\" | \"y3\";\nexport type XYSeriesDescriptor<K extends string = XYSeriesKey> = ChartSeriesDescriptor<K>;\nexport type BulletSeriesKey = \"value\" | \"target\";\nexport type BulletSeriesDescriptor = ChartSeriesDescriptor & { key: BulletSeriesKey };\n\nexport type XYPoint = { x: string | number; y: number; y2?: number; y3?: number };\nexport type NamedValue = { name: string; value: number };\nexport type RadarPoint = { subject: string; value: number };\nexport type BulletPoint = { name: string; value: number; target: number };\nexport type SankeyData = {\n\tnodes: { name: string }[];\n\tlinks: { source: number; target: number; value: number }[];\n};\n\nexport function resolveChartSeries<K extends string = string>(\n\tseries: Array<ChartSeriesDescriptor<K>> | undefined,\n\tfallbackKeys: K[],\n): Array<ChartSeriesDescriptor<K>> {\n\tif (series && series.length > 0) {\n\t\treturn series;\n\t}\n\treturn fallbackKeys.map((key) => ({ key }));\n}\n\nexport function applyLeadColor<K extends string = string>(\n\titems: Array<ChartSeriesDescriptor<K>>,\n\tcolor?: string,\n): Array<ChartSeriesDescriptor<K>> {\n\tif (!color) {\n\t\treturn items;\n\t}\n\treturn items.map((item, index) => (index === 0 ? { ...item, color: item.color ?? color } : item));\n}\n\nexport function xyFallbackKeys(data: Array<{ y2?: number; y3?: number }>): string[] {\n\tconst keys = [\"y\"];\n\tif (data.some((point) => point.y2 != null)) {\n\t\tkeys.push(\"y2\");\n\t}\n\tif (data.some((point) => point.y3 != null)) {\n\t\tkeys.push(\"y3\");\n\t}\n\treturn keys;\n}\n"],"mappings":";;AAoBA,SAAgBA,EACf,GACA,GACkC;CAIlC,OAHIC,KAAUA,EAAO,SAAS,IACtBA,IAEDC,EAAa,KAAK,OAAS,EAAE,OAAI,EAAE;AAC3C;AAEA,SAAgBC,EACf,GACA,GACkC;CAIlC,OAHKC,IAGEC,EAAM,KAAK,GAAM,MAAWC,MAAU,IAAI;EAAE,GAAGC;EAAM,OAAOA,EAAK,SAASH;CAAM,IAAIG,CAAK,IAFxFF;AAGT;AAEA,SAAgBG,EAAe,GAAqD;CACnF,IAAMC,IAAO,CAAC,GAAG;CAOjB,OANIC,EAAK,MAAM,MAAUC,EAAM,MAAM,IAAI,KACxCF,EAAK,KAAK,IAAI,GAEXC,EAAK,MAAM,MAAUC,EAAM,MAAM,IAAI,KACxCF,EAAK,KAAK,IAAI,GAERA;AACR"}
@@ -35,13 +35,13 @@ function _(e) {
35
35
  })
36
36
  });
37
37
  }
38
- function v({ items: a, ariaLabel: o = "Slot bar chart", heightClass: s = "h-6", gapClass: c = "gap-px", emptyClass: l = "bg-basalt-muted", className: u }) {
38
+ function v({ items: a, ariaLabel: o = "Slot bar chart", heightClass: s = "h-basalt-6", gapClass: c = "gap-px", emptyClass: l = "bg-basalt-muted", className: u }) {
39
39
  if (a.length === 0) return null;
40
40
  let p = a.some((e) => e.label);
41
41
  function m(t) {
42
42
  let n = t.height ?? 1, r = n <= 0, i = t.color.startsWith("bg-"), a = r ? 100 : Math.max(n * 100, 10);
43
43
  return /* @__PURE__ */ d("div", {
44
- className: e("w-full rounded-sm", r ? l : i ? t.color : void 0),
44
+ className: e("w-full rounded-basalt-sm", r ? l : i ? t.color : void 0),
45
45
  style: {
46
46
  height: `${a}%`,
47
47
  ...r || i ? {} : { backgroundColor: t.color }
@@ -1 +1 @@
1
- {"version":3,"file":"slot-bar.js","names":[],"sources":["../../src/charts/slot-bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, BarChart as RechartsBar, XAxis, YAxis } from \"recharts\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { ANIMATION_PROPS, BAR_RADIUS, cartesianAxisProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { LineChartNumericKeys } from \"./line\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type SlotBarItem = {\n\tcolor: string;\n\theight?: number;\n\tlabel?: string;\n};\n\nexport type SlotBarItemsProps = {\n\titems: SlotBarItem[];\n\tariaLabel?: string;\n\theightClass?: string;\n\tgapClass?: string;\n\temptyClass?: string;\n\tclassName?: string;\n};\n\nexport type SlotBarDataProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport type SlotBarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = SlotBarItemsProps | SlotBarDataProps<TData, K>;\n\nexport function SlotBarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>(props: SlotBarChartProps<TData, K>) {\n\tif (\"items\" in props) {\n\t\treturn <SlotItemBars {...props} />;\n\t}\n\tconst {\n\t\tseries,\n\t\tariaLabel = \"Slot bar chart\",\n\t\tclassName,\n\t\tsummary,\n\t\tdataAlternative,\n\t\taccessibilityLayer,\n\t} = props;\n\tconst bars = resolveChartSeries(series, [\"y\" as K]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={props.data}>\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(true)} />\n\t\t\t\t<YAxis {...cartesianAxisProps(true)} />\n\t\t\t\t{bars.map((item, index) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, index)}\n\t\t\t\t\t\tradius={BAR_RADIUS.vertical}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartFrame>\n\t);\n}\n\nfunction SlotItemBars({\n\titems,\n\tariaLabel = \"Slot bar chart\",\n\theightClass = \"h-6\",\n\tgapClass = \"gap-px\",\n\temptyClass = \"bg-basalt-muted\",\n\tclassName,\n}: SlotBarItemsProps) {\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\tconst hasTooltips = items.some((item) => item.label);\n\tfunction renderBar(item: SlotBarItem) {\n\t\tconst heightRatio = item.height ?? 1;\n\t\tconst isEmpty = heightRatio <= 0;\n\t\tconst isTailwindColor = item.color.startsWith(\"bg-\");\n\t\tconst heightPercent = isEmpty ? 100 : Math.max(heightRatio * 100, 10);\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"w-full rounded-sm\",\n\t\t\t\t\tisEmpty ? emptyClass : isTailwindColor ? item.color : undefined,\n\t\t\t\t)}\n\t\t\t\tstyle={{\n\t\t\t\t\theight: `${heightPercent}%`,\n\t\t\t\t\t...(isEmpty || isTailwindColor ? {} : { backgroundColor: item.color }),\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"slot-bar\"\n\t\t\t/>\n\t\t);\n\t}\n\tconst content = items.map((item, index) => {\n\t\tconst bar =\n\t\t\thasTooltips && item.label ? (\n\t\t\t\t<Tooltip>\n\t\t\t\t\t<TooltipTrigger asChild>{renderBar(item)}</TooltipTrigger>\n\t\t\t\t\t<TooltipContent side=\"top\">\n\t\t\t\t\t\t<p>{item.label}</p>\n\t\t\t\t\t</TooltipContent>\n\t\t\t\t</Tooltip>\n\t\t\t) : (\n\t\t\t\trenderBar(item)\n\t\t\t);\n\t\treturn (\n\t\t\t<div\n\t\t\t\tkey={`${item.label ?? item.color}-${index}`}\n\t\t\t\tclassName=\"flex min-h-0 min-w-0 flex-1 items-end self-stretch\"\n\t\t\t>\n\t\t\t\t{bar}\n\t\t\t</div>\n\t\t);\n\t});\n\tconst container = (\n\t\t<div\n\t\t\tclassName={cn(\"flex w-full items-end\", heightClass, gapClass, className)}\n\t\t\trole=\"img\"\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t);\n\tif (hasTooltips) {\n\t\treturn <TooltipProvider delayDuration={0}>{container}</TooltipProvider>;\n\t}\n\treturn container;\n}\n"],"mappings":";;;;;;;;;AA+DA,SAAgB,EAGd,GAAoC;CACrC,IAAI,WAAW,GACd,OAAO,kBAAC,GAAD,EAAc,GAAI,EAAQ,CAAA;CAElC,IAAM,EACL,WACA,eAAY,kBACZ,cACA,YACA,oBACA,0BACG,GACE,IAAO,EAAmB,GAAQ,CAAC,GAAQ,CAAC;CAClD,OACC,kBAAC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAAC,GAAD;GAAa,MAAM,EAAM;GAAzB,UAAA;IACC,kBAAC,GAAD;KAAO,SAAQ;KAAI,GAAI,EAAmB,EAAI;IAAI,CAAA;IAClD,kBAAC,GAAD,EAAO,GAAI,EAAmB,EAAI,EAAI,CAAA;IACrC,EAAK,KAAK,GAAM,MAChB,kBAAC,GAAD;KAEC,SAAS,EAAK;KACd,MAAM,EAAK,SAAS,EAAK;KACzB,MAAM,EAAY,GAAM,CAAK;KAC7B,QAAQ,EAAW;KACnB,GAAI;IACJ,GANK,EAAK,GAMV,CACD;GACW;;CACF,CAAA;AAEd;AAEA,SAAS,EAAa,EACrB,UACA,eAAY,kBACZ,iBAAc,OACd,cAAW,UACX,gBAAa,mBACb,gBACqB;CACrB,IAAI,EAAM,WAAW,GACpB,OAAO;CAER,IAAM,IAAc,EAAM,MAAM,MAAS,EAAK,KAAK;CACnD,SAAS,EAAU,GAAmB;EACrC,IAAM,IAAc,EAAK,UAAU,GAC7B,IAAU,KAAe,GACzB,IAAkB,EAAK,MAAM,WAAW,KAAK,GAC7C,IAAgB,IAAU,MAAM,KAAK,IAAI,IAAc,KAAK,EAAE;EACpE,OACC,kBAAC,OAAD;GACC,WAAW,EACV,qBACA,IAAU,IAAa,IAAkB,EAAK,QAAQ,KAAA,CACvD;GACA,OAAO;IACN,QAAQ,GAAG,EAAc;IACzB,GAAI,KAAW,IAAkB,CAAC,IAAI,EAAE,iBAAiB,EAAK,MAAM;GACrE;GACA,eAAY;EACZ,CAAA;CAEH;CACA,IAAM,IAAU,EAAM,KAAK,GAAM,MAAU;EAC1C,IAAM,IACL,KAAe,EAAK,QACnB,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,GAAD;GAAgB,SAAA;GAAS,UAAA,EAAU,CAAI;EAAkB,CAAA,GACzD,kBAAC,GAAD;GAAgB,MAAK;GACpB,UAAA,kBAAC,KAAD,EAAA,UAAI,EAAK,MAAS,CAAA;EACH,CAAA,CACR,EAAA,CAAA,IAET,EAAU,CAAI;EAEhB,OACC,kBAAC,OAAD;GAEC,WAAU;GAET,UAAA;EACG,GAJC,GAAG,EAAK,SAAS,EAAK,MAAM,GAAG,GAIhC;CAEP,CAAC,GACK,IACL,kBAAC,OAAD;EACC,WAAW,EAAG,yBAAyB,GAAa,GAAU,CAAS;EACvE,MAAK;EACL,cAAY;EAEX,UAAA;CACG,CAAA;CAKN,OAHI,IACI,kBAAC,GAAD;EAAiB,eAAe;EAAI,UAAA;CAA2B,CAAA,IAEhE;AACR"}
1
+ {"version":3,"file":"slot-bar.js","names":["RechartsBar","Tooltip","Tooltip$1","SlotBarChart","props","SlotItemBars","bars","resolveChartSeries","series","ChartFrame","BarChart","XAxis","cartesianAxisProps","YAxis","Bar","item","seriesColor","index","BAR_RADIUS","ANIMATION_PROPS","items","hasTooltips","renderBar","heightRatio","isEmpty","isTailwindColor","heightPercent","cn","emptyClass","content","bar","TooltipTrigger","TooltipContent","container","heightClass","gapClass","className","ariaLabel","TooltipProvider"],"sources":["../../src/charts/slot-bar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, BarChart as RechartsBar, XAxis, YAxis } from \"recharts\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../components/tooltip\";\nimport { cn } from \"../utils/cn\";\nimport { ANIMATION_PROPS, BAR_RADIUS, cartesianAxisProps, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { LineChartNumericKeys } from \"./line\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type SlotBarItem = {\n\tcolor: string;\n\theight?: number;\n\tlabel?: string;\n};\n\nexport type SlotBarItemsProps = {\n\titems: SlotBarItem[];\n\tariaLabel?: string;\n\theightClass?: string;\n\tgapClass?: string;\n\temptyClass?: string;\n\tclassName?: string;\n};\n\nexport type SlotBarDataProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport type SlotBarChartProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = SlotBarItemsProps | SlotBarDataProps<TData, K>;\n\nexport function SlotBarChart<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>(props: SlotBarChartProps<TData, K>) {\n\tif (\"items\" in props) {\n\t\treturn <SlotItemBars {...props} />;\n\t}\n\tconst {\n\t\tseries,\n\t\tariaLabel = \"Slot bar chart\",\n\t\tclassName,\n\t\tsummary,\n\t\tdataAlternative,\n\t\taccessibilityLayer,\n\t} = props;\n\tconst bars = resolveChartSeries(series, [\"y\" as K]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar data={props.data}>\n\t\t\t\t<XAxis dataKey=\"x\" {...cartesianAxisProps(true)} />\n\t\t\t\t<YAxis {...cartesianAxisProps(true)} />\n\t\t\t\t{bars.map((item, index) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={seriesColor(item, index)}\n\t\t\t\t\t\tradius={BAR_RADIUS.vertical}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartFrame>\n\t);\n}\n\nfunction SlotItemBars({\n\titems,\n\tariaLabel = \"Slot bar chart\",\n\theightClass = \"h-basalt-6\",\n\tgapClass = \"gap-px\",\n\temptyClass = \"bg-basalt-muted\",\n\tclassName,\n}: SlotBarItemsProps) {\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\tconst hasTooltips = items.some((item) => item.label);\n\tfunction renderBar(item: SlotBarItem) {\n\t\tconst heightRatio = item.height ?? 1;\n\t\tconst isEmpty = heightRatio <= 0;\n\t\tconst isTailwindColor = item.color.startsWith(\"bg-\");\n\t\tconst heightPercent = isEmpty ? 100 : Math.max(heightRatio * 100, 10);\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"w-full rounded-basalt-sm\",\n\t\t\t\t\tisEmpty ? emptyClass : isTailwindColor ? item.color : undefined,\n\t\t\t\t)}\n\t\t\t\tstyle={{\n\t\t\t\t\theight: `${heightPercent}%`,\n\t\t\t\t\t...(isEmpty || isTailwindColor ? {} : { backgroundColor: item.color }),\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"slot-bar\"\n\t\t\t/>\n\t\t);\n\t}\n\tconst content = items.map((item, index) => {\n\t\tconst bar =\n\t\t\thasTooltips && item.label ? (\n\t\t\t\t<Tooltip>\n\t\t\t\t\t<TooltipTrigger asChild>{renderBar(item)}</TooltipTrigger>\n\t\t\t\t\t<TooltipContent side=\"top\">\n\t\t\t\t\t\t<p>{item.label}</p>\n\t\t\t\t\t</TooltipContent>\n\t\t\t\t</Tooltip>\n\t\t\t) : (\n\t\t\t\trenderBar(item)\n\t\t\t);\n\t\treturn (\n\t\t\t<div\n\t\t\t\tkey={`${item.label ?? item.color}-${index}`}\n\t\t\t\tclassName=\"flex min-h-0 min-w-0 flex-1 items-end self-stretch\"\n\t\t\t>\n\t\t\t\t{bar}\n\t\t\t</div>\n\t\t);\n\t});\n\tconst container = (\n\t\t<div\n\t\t\tclassName={cn(\"flex w-full items-end\", heightClass, gapClass, className)}\n\t\t\trole=\"img\"\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t);\n\tif (hasTooltips) {\n\t\treturn <TooltipProvider delayDuration={0}>{container}</TooltipProvider>;\n\t}\n\treturn container;\n}\n"],"mappings":";;;;;;;;;AA+DA,SAAgBG,EAGd,GAAoC;CACrC,IAAI,WAAWC,GACd,OAAO,kBAACC,GAAD,EAAc,GAAID,EAAQ,CAAA;CAElC,IAAM,EACL,WACA,eAAY,kBACZ,cACA,YACA,oBACA,0BACGA,GACEE,IAAOC,EAAmBC,GAAQ,CAAC,GAAQ,CAAC;CAClD,OACC,kBAACC,GAAD;EACY;EACA;EACF;EACQ;EACG;EAEpB,UAAA,kBAACT,GAAD;GAAa,MAAMI,EAAM;GAAzB,UAAA;IACC,kBAACO,GAAD;KAAO,SAAQ;KAAI,GAAIC,EAAmB,EAAI;IAAI,CAAA;IAClD,kBAACC,GAAD,EAAO,GAAID,EAAmB,EAAI,EAAI,CAAA;IACrCN,EAAK,KAAK,GAAM,MAChB,kBAACQ,GAAD;KAEC,SAASC,EAAK;KACd,MAAMA,EAAK,SAASA,EAAK;KACzB,MAAMC,EAAYD,GAAME,CAAK;KAC7B,QAAQC,EAAW;KACnB,GAAIC;IACJ,GANKJ,EAAK,GAMV,CACD;GACW;;CACF,CAAA;AAEd;AAEA,SAASV,EAAa,EACrB,UACA,eAAY,kBACZ,iBAAc,cACd,cAAW,UACX,gBAAa,mBACb,gBACqB;CACrB,IAAIe,EAAM,WAAW,GACpB,OAAO;CAER,IAAMC,IAAcD,EAAM,MAAM,MAASL,EAAK,KAAK;CACnD,SAASO,EAAU,GAAmB;EACrC,IAAMC,IAAcR,EAAK,UAAU,GAC7BS,IAAUD,KAAe,GACzBE,IAAkBV,EAAK,MAAM,WAAW,KAAK,GAC7CW,IAAgBF,IAAU,MAAM,KAAK,IAAID,IAAc,KAAK,EAAE;EACpE,OACC,kBAAC,OAAD;GACC,WAAWI,EACV,4BACAH,IAAUI,IAAaH,IAAkBV,EAAK,QAAQ,KAAA,CACvD;GACA,OAAO;IACN,QAAQ,GAAGW,EAAc;IACzB,GAAIF,KAAWC,IAAkB,CAAC,IAAI,EAAE,iBAAiBV,EAAK,MAAM;GACrE;GACA,eAAY;EACZ,CAAA;CAEH;CACA,IAAMc,IAAUT,EAAM,KAAK,GAAM,MAAU;EAC1C,IAAMU,IACLT,KAAeN,EAAK,QACnB,kBAACd,GAAD,EAAA,UAAA,CACC,kBAAC8B,GAAD;GAAgB,SAAA;GAAS,UAAAT,EAAUP,CAAI;EAAkB,CAAA,GACzD,kBAACiB,GAAD;GAAgB,MAAK;GACpB,UAAA,kBAAC,KAAD,EAAA,UAAIjB,EAAK,MAAS,CAAA;EACH,CAAA,CACR,EAAA,CAAA,IAETO,EAAUP,CAAI;EAEhB,OACC,kBAAC,OAAD;GAEC,WAAU;GAET,UAAAe;EACG,GAJC,GAAGf,EAAK,SAASA,EAAK,MAAM,GAAGE,GAIhC;CAEP,CAAC,GACKgB,IACL,kBAAC,OAAD;EACC,WAAWN,EAAG,yBAAyBO,GAAaC,GAAUC,CAAS;EACvE,MAAK;EACL,cAAYC;EAEX,UAAAR;CACG,CAAA;CAKN,OAHIR,IACI,kBAACiB,GAAD;EAAiB,eAAe;EAAI,UAAAL;CAA2B,CAAA,IAEhEA;AACR"}
@@ -1,34 +1,49 @@
1
1
  "use client";
2
- import { ANIMATION_PROPS as e, CHART_TYPE as t, seriesColor as n } from "./config.js";
2
+ import { chart as e } from "./palette.js";
3
+ import { ANIMATION_PROPS as t, seriesColor as n } from "./config.js";
3
4
  import { resolveChartSeries as r } from "./series.js";
4
5
  import { ChartFrame as i } from "./frame.js";
5
- import { jsx as a } from "react/jsx-runtime";
6
- import { Line as o, LineChart as s } from "recharts";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ import { Bar as s, BarChart as c, Cell as l, XAxis as u, YAxis as d } from "recharts";
7
8
  //#region src/charts/sparkline.tsx
8
- function c({ data: c, series: l, ariaLabel: u = "Sparkline", className: d, summary: f, dataAlternative: p, accessibilityLayer: m }) {
9
- let h = r(l, ["y"]);
9
+ function f({ data: f, series: p, ariaLabel: m = "Sparkline", className: h, summary: g, dataAlternative: _, accessibilityLayer: v }) {
10
+ let y = r(p, ["y"]);
10
11
  return /* @__PURE__ */ a(i, {
11
- ariaLabel: u,
12
- className: d,
13
- size: "h-10 w-28",
14
- summary: f,
15
- dataAlternative: p,
16
- accessibilityLayer: m,
17
- children: /* @__PURE__ */ a(s, {
18
- data: c,
19
- children: h.map((r, i) => /* @__PURE__ */ a(o, {
20
- type: "monotone",
21
- dataKey: r.key,
22
- name: r.label ?? r.key,
23
- stroke: n(r, i),
24
- strokeWidth: t.strokeWidth,
25
- dot: !1,
26
- ...e
27
- }, r.key))
12
+ ariaLabel: m,
13
+ className: h,
14
+ size: "h-basalt-5 w-basalt-28",
15
+ summary: g,
16
+ dataAlternative: _,
17
+ accessibilityLayer: v,
18
+ children: /* @__PURE__ */ o(c, {
19
+ data: f,
20
+ margin: {
21
+ top: 0,
22
+ right: 0,
23
+ bottom: 0,
24
+ left: 0
25
+ },
26
+ barCategoryGap: "12%",
27
+ barGap: 1,
28
+ children: [
29
+ /* @__PURE__ */ a(u, {
30
+ dataKey: "x",
31
+ hide: !0
32
+ }),
33
+ /* @__PURE__ */ a(d, { hide: !0 }),
34
+ y.map((r, i) => /* @__PURE__ */ a(s, {
35
+ dataKey: r.key,
36
+ name: r.label ?? r.key,
37
+ fill: r.color ?? (y.length === 1 ? e.green : n(r, i)),
38
+ radius: 1,
39
+ ...t,
40
+ children: f.map((e, t) => /* @__PURE__ */ a(l, { fillOpacity: t % 3 == 0 ? .4 : 1 }, `${e.x}-${t}`))
41
+ }, r.key))
42
+ ]
28
43
  })
29
44
  });
30
45
  }
31
46
  //#endregion
32
- export { c as Sparkline };
47
+ export { f as Sparkline };
33
48
 
34
49
  //# sourceMappingURL=sparkline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sparkline.js","names":[],"sources":["../../src/charts/sparkline.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Line, LineChart as RechartsLine } from \"recharts\";\nimport { ANIMATION_PROPS, CHART_TYPE, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { LineChartNumericKeys } from \"./line\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type SparklineProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Sparkline<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Sparkline\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: SparklineProps<TData, K>) {\n\tconst lines = resolveChartSeries(series, [\"y\" as K]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsize=\"h-10 w-28\"\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsLine data={data}>\n\t\t\t\t{lines.map((item, index) => (\n\t\t\t\t\t<Line\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\ttype=\"monotone\"\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tstroke={seriesColor(item, index)}\n\t\t\t\t\t\tstrokeWidth={CHART_TYPE.strokeWidth}\n\t\t\t\t\t\tdot={false}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</RechartsLine>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;AAyCA,SAAgB,EAGd,EACD,SACA,WACA,eAAY,aACZ,cACA,YACA,oBACA,yBAC4B;CAC5B,IAAM,IAAQ,EAAmB,GAAQ,CAAC,GAAQ,CAAC;CACnD,OACC,kBAAC,GAAD;EACY;EACA;EACX,MAAK;EACI;EACQ;EACG;EAEpB,UAAA,kBAAC,GAAD;GAAoB;GAClB,UAAA,EAAM,KAAK,GAAM,MACjB,kBAAC,GAAD;IAEC,MAAK;IACL,SAAS,EAAK;IACd,MAAM,EAAK,SAAS,EAAK;IACzB,QAAQ,EAAY,GAAM,CAAK;IAC/B,aAAa,EAAW;IACxB,KAAK;IACL,GAAI;GACJ,GARK,EAAK,GAQV,CACD;EACY,CAAA;CACH,CAAA;AAEd"}
1
+ {"version":3,"file":"sparkline.js","names":["RechartsBar","Sparkline","bars","resolveChartSeries","series","ChartFrame","BarChart","XAxis","YAxis","Bar","item","chart","seriesColor","index","ANIMATION_PROPS","data","Cell","pointIndex","point"],"sources":["../../src/charts/sparkline.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Bar, Cell, BarChart as RechartsBar, XAxis, YAxis } from \"recharts\";\nimport { ANIMATION_PROPS, seriesColor } from \"./config\";\nimport { ChartFrame } from \"./frame\";\nimport type { LineChartNumericKeys } from \"./line\";\nimport { chart } from \"./palette\";\nimport { type ChartSeriesDescriptor, resolveChartSeries, type XYPoint } from \"./series\";\n\nexport type SparklineProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Sparkline<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({\n\tdata,\n\tseries,\n\tariaLabel = \"Sparkline\",\n\tclassName,\n\tsummary,\n\tdataAlternative,\n\taccessibilityLayer,\n}: SparklineProps<TData, K>) {\n\tconst bars = resolveChartSeries(series, [\"y\" as K]);\n\treturn (\n\t\t<ChartFrame\n\t\t\tariaLabel={ariaLabel}\n\t\t\tclassName={className}\n\t\t\tsize=\"h-basalt-5 w-basalt-28\"\n\t\t\tsummary={summary}\n\t\t\tdataAlternative={dataAlternative}\n\t\t\taccessibilityLayer={accessibilityLayer}\n\t\t>\n\t\t\t<RechartsBar\n\t\t\t\tdata={data}\n\t\t\t\tmargin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n\t\t\t\tbarCategoryGap=\"12%\"\n\t\t\t\tbarGap={1}\n\t\t\t>\n\t\t\t\t<XAxis dataKey=\"x\" hide />\n\t\t\t\t<YAxis hide />\n\t\t\t\t{bars.map((item, index) => (\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tkey={item.key}\n\t\t\t\t\t\tdataKey={item.key}\n\t\t\t\t\t\tname={item.label ?? item.key}\n\t\t\t\t\t\tfill={item.color ?? (bars.length === 1 ? chart.green : seriesColor(item, index))}\n\t\t\t\t\t\tradius={1}\n\t\t\t\t\t\t{...ANIMATION_PROPS}\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.map((point, pointIndex) => (\n\t\t\t\t\t\t\t<Cell key={`${point.x}-${pointIndex}`} fillOpacity={pointIndex % 3 === 0 ? 0.4 : 1} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Bar>\n\t\t\t\t))}\n\t\t\t</RechartsBar>\n\t\t</ChartFrame>\n\t);\n}\n"],"mappings":";;;;;;;;AA0CA,SAAgBC,EAGd,EACD,SACA,WACA,eAAY,aACZ,cACA,YACA,oBACA,yBAC4B;CAC5B,IAAMC,IAAOC,EAAmBC,GAAQ,CAAC,GAAQ,CAAC;CAClD,OACC,kBAACC,GAAD;EACY;EACA;EACX,MAAK;EACI;EACQ;EACG;EAEpB,UAAA,kBAACL,GAAD;GACO;GACN,QAAQ;IAAE,KAAK;IAAG,OAAO;IAAG,QAAQ;IAAG,MAAM;GAAE;GAC/C,gBAAe;GACf,QAAQ;GAJT,UAAA;IAMC,kBAACO,GAAD;KAAO,SAAQ;KAAI,MAAA;IAAM,CAAA;IACzB,kBAACC,GAAD,EAAO,MAAA,GAAM,CAAA;IACZN,EAAK,KAAK,GAAM,MAChB,kBAACO,GAAD;KAEC,SAASC,EAAK;KACd,MAAMA,EAAK,SAASA,EAAK;KACzB,MAAMA,EAAK,UAAUR,EAAK,WAAW,IAAIS,EAAM,QAAQC,EAAYF,GAAMG,CAAK;KAC9E,QAAQ;KACR,GAAIC;KAEH,UAAAC,EAAK,KAAK,GAAO,MACjB,kBAACC,GAAD,EAAuC,aAAaC,IAAa,KAAM,IAAI,KAAM,EAAI,GAA1E,GAAGC,EAAM,EAAE,GAAGD,GAA4D,CACrF;IACG,GAVCP,EAAK,GAUN,CACL;GACW;;CACF,CAAA;AAEd"}