cortena-ui 1.3.0 → 1.4.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 (280) hide show
  1. package/README.md +74 -3
  2. package/dist/a2ui/catalogue-doc.d.ts +44 -0
  3. package/dist/a2ui/catalogue-doc.js +169 -0
  4. package/dist/a2ui/catalogue-doc.js.map +1 -0
  5. package/dist/a2ui/catalogue.d.ts +44 -0
  6. package/dist/a2ui/catalogue.js +942 -0
  7. package/dist/a2ui/catalogue.js.map +1 -0
  8. package/dist/a2ui/index.d.ts +7 -0
  9. package/dist/a2ui/message.d.ts +232 -0
  10. package/dist/a2ui/message.js +365 -0
  11. package/dist/a2ui/message.js.map +1 -0
  12. package/dist/a2ui/renderer.d.ts +46 -0
  13. package/dist/a2ui/renderer.js +252 -0
  14. package/dist/a2ui/renderer.js.map +1 -0
  15. package/dist/a2ui/views.d.ts +80 -0
  16. package/dist/a2ui/views.js +596 -0
  17. package/dist/a2ui/views.js.map +1 -0
  18. package/dist/a2ui.d.ts +8 -0
  19. package/dist/a2ui.js +7 -0
  20. package/dist/chart.d.ts +9 -0
  21. package/dist/chart.js +9 -0
  22. package/dist/components/accordion.d.ts +22 -0
  23. package/dist/components/accordion.js +63 -0
  24. package/dist/components/accordion.js.map +1 -0
  25. package/dist/components/alert.d.ts +15 -0
  26. package/dist/components/alert.js +64 -0
  27. package/dist/components/alert.js.map +1 -0
  28. package/dist/components/avatar.d.ts +18 -0
  29. package/dist/components/avatar.js +40 -0
  30. package/dist/components/avatar.js.map +1 -0
  31. package/dist/components/badge.d.ts +12 -0
  32. package/dist/components/badge.js +47 -0
  33. package/dist/components/badge.js.map +1 -0
  34. package/dist/components/breadcrumb.d.ts +71 -0
  35. package/dist/components/breadcrumb.js +123 -0
  36. package/dist/components/breadcrumb.js.map +1 -0
  37. package/dist/components/button-link.d.ts +28 -0
  38. package/dist/components/button-link.js +24 -0
  39. package/dist/components/button-link.js.map +1 -0
  40. package/dist/components/button.d.ts +24 -0
  41. package/dist/components/button.js +65 -0
  42. package/dist/components/button.js.map +1 -0
  43. package/dist/components/calendar.d.ts +28 -0
  44. package/dist/components/calendar.js +123 -0
  45. package/dist/components/calendar.js.map +1 -0
  46. package/dist/components/card.d.ts +32 -0
  47. package/dist/components/card.js +57 -0
  48. package/dist/components/card.js.map +1 -0
  49. package/dist/components/chart/chart.d.ts +71 -0
  50. package/dist/components/chart/chart.js +167 -0
  51. package/dist/components/chart/chart.js.map +1 -0
  52. package/dist/components/chart/container.d.ts +88 -0
  53. package/dist/components/chart/container.js +189 -0
  54. package/dist/components/chart/container.js.map +1 -0
  55. package/dist/components/chart/data.js +128 -0
  56. package/dist/components/chart/data.js.map +1 -0
  57. package/dist/components/chart/index.d.ts +9 -0
  58. package/dist/components/chart/index.js +10 -0
  59. package/dist/components/chart/nivo-charts.js +225 -0
  60. package/dist/components/chart/nivo-charts.js.map +1 -0
  61. package/dist/components/chart/nivo-lazy.js +50 -0
  62. package/dist/components/chart/nivo-lazy.js.map +1 -0
  63. package/dist/components/chart/nivo-theme.d.ts +156 -0
  64. package/dist/components/chart/nivo-theme.js +161 -0
  65. package/dist/components/chart/nivo-theme.js.map +1 -0
  66. package/dist/components/chart/recharts-charts.js +276 -0
  67. package/dist/components/chart/recharts-charts.js.map +1 -0
  68. package/dist/components/chart/recharts-lazy.js +58 -0
  69. package/dist/components/chart/recharts-lazy.js.map +1 -0
  70. package/dist/components/chart/recharts-parts.d.ts +10 -0
  71. package/dist/components/chart/recharts-parts.js +25 -0
  72. package/dist/components/chart/recharts-parts.js.map +1 -0
  73. package/dist/components/chart/tokens.d.ts +62 -0
  74. package/dist/components/chart/tokens.js +192 -0
  75. package/dist/components/chart/tokens.js.map +1 -0
  76. package/dist/components/chart/types.d.ts +114 -0
  77. package/dist/components/chart/types.js +27 -0
  78. package/dist/components/chart/types.js.map +1 -0
  79. package/dist/components/checkbox.d.ts +20 -0
  80. package/dist/components/checkbox.js +24 -0
  81. package/dist/components/checkbox.js.map +1 -0
  82. package/dist/components/chip.d.ts +17 -0
  83. package/dist/components/chip.js +47 -0
  84. package/dist/components/chip.js.map +1 -0
  85. package/dist/components/combobox.d.ts +76 -0
  86. package/dist/components/combobox.js +201 -0
  87. package/dist/components/combobox.js.map +1 -0
  88. package/dist/components/command.d.ts +50 -0
  89. package/dist/components/command.js +117 -0
  90. package/dist/components/command.js.map +1 -0
  91. package/dist/components/data-table/data-table.d.ts +65 -0
  92. package/dist/components/data-table/data-table.js +588 -0
  93. package/dist/components/data-table/data-table.js.map +1 -0
  94. package/dist/components/data-table/export.d.ts +23 -0
  95. package/dist/components/data-table/export.js +95 -0
  96. package/dist/components/data-table/export.js.map +1 -0
  97. package/dist/components/data-table/features.d.ts +66 -0
  98. package/dist/components/data-table/features.js +103 -0
  99. package/dist/components/data-table/features.js.map +1 -0
  100. package/dist/components/data-table/index.d.ts +8 -0
  101. package/dist/components/data-table/parts.d.ts +79 -0
  102. package/dist/components/data-table/parts.js +400 -0
  103. package/dist/components/data-table/parts.js.map +1 -0
  104. package/dist/components/data-table/system-columns.js +84 -0
  105. package/dist/components/data-table/system-columns.js.map +1 -0
  106. package/dist/components/data-table/types.d.ts +172 -0
  107. package/dist/components/data-table/use-data-table.d.ts +19 -0
  108. package/dist/components/data-table/use-data-table.js +171 -0
  109. package/dist/components/data-table/use-data-table.js.map +1 -0
  110. package/dist/components/data-table/use-server-source.js +200 -0
  111. package/dist/components/data-table/use-server-source.js.map +1 -0
  112. package/dist/components/date-field.d.ts +54 -0
  113. package/dist/components/date-field.js +235 -0
  114. package/dist/components/date-field.js.map +1 -0
  115. package/dist/components/date-picker.d.ts +42 -0
  116. package/dist/components/date-picker.js +125 -0
  117. package/dist/components/date-picker.js.map +1 -0
  118. package/dist/components/dialog.d.ts +36 -0
  119. package/dist/components/dialog.js +97 -0
  120. package/dist/components/dialog.js.map +1 -0
  121. package/dist/components/dropdown-menu.d.ts +54 -0
  122. package/dist/components/dropdown-menu.js +191 -0
  123. package/dist/components/dropdown-menu.js.map +1 -0
  124. package/dist/components/dropzone.d.ts +48 -0
  125. package/dist/components/dropzone.js +185 -0
  126. package/dist/components/dropzone.js.map +1 -0
  127. package/dist/components/empty-state.d.ts +22 -0
  128. package/dist/components/empty-state.js +46 -0
  129. package/dist/components/empty-state.js.map +1 -0
  130. package/dist/components/error-banner.d.ts +17 -0
  131. package/dist/components/error-banner.js +52 -0
  132. package/dist/components/error-banner.js.map +1 -0
  133. package/dist/components/field.d.ts +64 -0
  134. package/dist/components/field.js +133 -0
  135. package/dist/components/field.js.map +1 -0
  136. package/dist/components/form.d.ts +37 -0
  137. package/dist/components/form.js +103 -0
  138. package/dist/components/form.js.map +1 -0
  139. package/dist/components/input.d.ts +17 -0
  140. package/dist/components/input.js +26 -0
  141. package/dist/components/input.js.map +1 -0
  142. package/dist/components/kbd.d.ts +11 -0
  143. package/dist/components/kbd.js +20 -0
  144. package/dist/components/kbd.js.map +1 -0
  145. package/dist/components/label.d.ts +14 -0
  146. package/dist/components/label.js +28 -0
  147. package/dist/components/label.js.map +1 -0
  148. package/dist/components/loading-skeleton.d.ts +22 -0
  149. package/dist/components/loading-skeleton.js +123 -0
  150. package/dist/components/loading-skeleton.js.map +1 -0
  151. package/dist/components/markdown.d.ts +44 -0
  152. package/dist/components/markdown.js +231 -0
  153. package/dist/components/markdown.js.map +1 -0
  154. package/dist/components/page-header.d.ts +26 -0
  155. package/dist/components/page-header.js +53 -0
  156. package/dist/components/page-header.js.map +1 -0
  157. package/dist/components/popover.d.ts +29 -0
  158. package/dist/components/popover.js +74 -0
  159. package/dist/components/popover.js.map +1 -0
  160. package/dist/components/progress.d.ts +22 -0
  161. package/dist/components/progress.js +49 -0
  162. package/dist/components/progress.js.map +1 -0
  163. package/dist/components/radio-group.d.ts +20 -0
  164. package/dist/components/radio-group.js +29 -0
  165. package/dist/components/radio-group.js.map +1 -0
  166. package/dist/components/scroll-area.d.ts +25 -0
  167. package/dist/components/scroll-area.js +39 -0
  168. package/dist/components/scroll-area.js.map +1 -0
  169. package/dist/components/section-card.d.ts +29 -0
  170. package/dist/components/section-card.js +55 -0
  171. package/dist/components/section-card.js.map +1 -0
  172. package/dist/components/segmented.d.ts +27 -0
  173. package/dist/components/segmented.js +32 -0
  174. package/dist/components/segmented.js.map +1 -0
  175. package/dist/components/select.d.ts +62 -0
  176. package/dist/components/select.js +97 -0
  177. package/dist/components/select.js.map +1 -0
  178. package/dist/components/separator.d.ts +19 -0
  179. package/dist/components/separator.js +23 -0
  180. package/dist/components/separator.js.map +1 -0
  181. package/dist/components/sheet.d.ts +35 -0
  182. package/dist/components/sheet.js +131 -0
  183. package/dist/components/sheet.js.map +1 -0
  184. package/dist/components/skeleton.d.ts +12 -0
  185. package/dist/components/skeleton.js +22 -0
  186. package/dist/components/skeleton.js.map +1 -0
  187. package/dist/components/sortable-list.d.ts +67 -0
  188. package/dist/components/sortable-list.js +206 -0
  189. package/dist/components/sortable-list.js.map +1 -0
  190. package/dist/components/spinner.d.ts +29 -0
  191. package/dist/components/spinner.js +34 -0
  192. package/dist/components/spinner.js.map +1 -0
  193. package/dist/components/status-dot.d.ts +26 -0
  194. package/dist/components/status-dot.js +47 -0
  195. package/dist/components/status-dot.js.map +1 -0
  196. package/dist/components/switch.d.ts +21 -0
  197. package/dist/components/switch.js +21 -0
  198. package/dist/components/switch.js.map +1 -0
  199. package/dist/components/tabs.d.ts +24 -0
  200. package/dist/components/tabs.js +60 -0
  201. package/dist/components/tabs.js.map +1 -0
  202. package/dist/components/textarea.d.ts +19 -0
  203. package/dist/components/textarea.js +47 -0
  204. package/dist/components/textarea.js.map +1 -0
  205. package/dist/components/toast.d.ts +47 -0
  206. package/dist/components/toast.js +106 -0
  207. package/dist/components/toast.js.map +1 -0
  208. package/dist/components/toolbar.d.ts +19 -0
  209. package/dist/components/toolbar.js +45 -0
  210. package/dist/components/toolbar.js.map +1 -0
  211. package/dist/components/tooltip.d.ts +28 -0
  212. package/dist/components/tooltip.js +59 -0
  213. package/dist/components/tooltip.js.map +1 -0
  214. package/dist/core.d.ts +44 -0
  215. package/dist/core.js +44 -0
  216. package/dist/data-table.d.ts +9 -0
  217. package/dist/data-table.js +7 -0
  218. package/dist/form.d.ts +7 -0
  219. package/dist/form.js +7 -0
  220. package/dist/hooks/use-cortena-theme.d.ts +98 -0
  221. package/dist/hooks/use-cortena-theme.js +145 -0
  222. package/dist/hooks/use-cortena-theme.js.map +1 -0
  223. package/dist/index.d.ts +75 -2678
  224. package/dist/index.js +66 -8598
  225. package/dist/lib/cn.d.ts +10 -0
  226. package/dist/lib/cn.js +15 -0
  227. package/dist/lib/cn.js.map +1 -0
  228. package/dist/lib/render.d.ts +23 -0
  229. package/dist/lib/render.js +20 -0
  230. package/dist/lib/render.js.map +1 -0
  231. package/dist/lib/shakeable.js +39 -0
  232. package/dist/lib/shakeable.js.map +1 -0
  233. package/dist/markdown.d.ts +3 -0
  234. package/dist/markdown.js +3 -0
  235. package/dist/sortable-list.d.ts +3 -0
  236. package/dist/sortable-list.js +3 -0
  237. package/package.json +37 -14
  238. package/src/a2ui/catalogue.ts +140 -103
  239. package/src/a2ui/views.tsx +5 -2
  240. package/src/components/alert.tsx +1 -1
  241. package/src/components/badge.tsx +1 -1
  242. package/src/components/button.tsx +1 -1
  243. package/src/components/chart/chart.tsx +72 -25
  244. package/src/components/chart/container.tsx +24 -39
  245. package/src/components/chart/index.tsx +4 -2
  246. package/src/components/chart/nivo-charts.tsx +41 -13
  247. package/src/components/chart/nivo-lazy.tsx +52 -0
  248. package/src/components/chart/recharts-charts.tsx +98 -3
  249. package/src/components/chart/recharts-lazy.tsx +72 -0
  250. package/src/components/chart/recharts-parts.tsx +34 -0
  251. package/src/components/chart/tokens.ts +1 -1
  252. package/src/components/chart/types.ts +14 -0
  253. package/src/components/chip.tsx +1 -1
  254. package/src/components/combobox.tsx +2 -2
  255. package/src/components/data-table/export.ts +18 -2
  256. package/src/components/data-table/features.ts +77 -45
  257. package/src/components/data-table/parts.tsx +15 -0
  258. package/src/components/data-table/use-data-table.ts +7 -2
  259. package/src/components/data-table/use-server-source.ts +17 -4
  260. package/src/components/date-field.tsx +1 -1
  261. package/src/components/error-banner.tsx +1 -1
  262. package/src/components/field.tsx +2 -2
  263. package/src/components/form.tsx +2 -2
  264. package/src/components/input.tsx +1 -1
  265. package/src/components/label.tsx +1 -1
  266. package/src/components/markdown.tsx +5 -4
  267. package/src/components/sheet.tsx +2 -2
  268. package/src/components/sortable-list.tsx +2 -2
  269. package/src/components/textarea.tsx +1 -1
  270. package/src/components/toast.tsx +1 -1
  271. package/src/entries/a2ui.ts +11 -0
  272. package/src/entries/chart.ts +10 -0
  273. package/src/entries/core.ts +91 -0
  274. package/src/entries/data-table.ts +9 -0
  275. package/src/entries/form.ts +24 -0
  276. package/src/entries/markdown.ts +9 -0
  277. package/src/entries/sortable-list.ts +13 -0
  278. package/src/index.ts +32 -98
  279. package/src/lib/shakeable.ts +33 -0
  280. package/dist/index.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { ChartConfig, ChartDataFor, ChartLabels, ChartRenderer, ChartScale, ChartType } from "./types.js";
3
+ import { ChartContainerProps } from "./container.js";
4
+ import * as React from "react";
5
+ //#region src/components/chart/chart.d.ts
6
+ export interface ChartProps<T extends ChartType = ChartType> extends Omit<ChartContainerProps, "children" | "config" | "responsive"> {
7
+ /** Which chart to draw; the package picks the engine. See {@link ChartType} for the data shape per type. */
8
+ type: T;
9
+ /** The data, in the shape documented on {@link ChartType}. */
10
+ data: ChartDataFor<T>;
11
+ /** Series presentation keyed by series id; colours default to `--ds-viz-1..n` in order. */
12
+ config?: ChartConfig;
13
+ /** Nivo renderer; `canvas` for large series. Ignored by the Recharts types and by sunburst. */
14
+ renderer?: ChartRenderer;
15
+ /** Category key for row data (bar, line, area, radar); inferred as the first string field. */
16
+ indexBy?: string;
17
+ /** Series keys for row data; inferred as every numeric field. */
18
+ keys?: string[];
19
+ /** Stack bars and areas instead of grouping them. */
20
+ stacked?: boolean;
21
+ /** Continuous scale for heatmap and calendar. Default sequential. */
22
+ scale?: ChartScale;
23
+ /** Show a legend. Default: when there is more than one series. */
24
+ legend?: boolean;
25
+ /** Draw grid lines (cartesian and radar types). Default true. */
26
+ grid?: boolean;
27
+ /** Show a tooltip on hover. Default true. */
28
+ tooltip?: boolean;
29
+ /**
30
+ * Per-arc labels for `pie` and `donut`; ignored by every other type. Default
31
+ * `percent`, which is what the reader almost always wants and what cortenaweb's
32
+ * donuts showed before this package existed. See {@link ChartLabels}.
33
+ */
34
+ labels?: ChartLabels;
35
+ /** Format values in axes, tooltips and labels. */
36
+ valueFormatter?: (value: number) => string;
37
+ /** Calendar range (ISO dates); defaults to the data's extent. */
38
+ from?: string;
39
+ to?: string;
40
+ /** Render the loading skeleton instead of the data. */
41
+ loading?: boolean;
42
+ /** Render the error state with this message instead of the data. */
43
+ error?: React.ReactNode | Error | null;
44
+ /** Content of the empty state. Default "No data". */
45
+ emptyMessage?: React.ReactNode;
46
+ }
47
+ /**
48
+ * Chart — one component for every chart type the fleet draws.
49
+ *
50
+ * `type` picks the engine: Recharts for bar, line, area, pie, donut, scatter,
51
+ * radar and funnel; Nivo for heatmap, calendar, treemap and sunburst, with
52
+ * `renderer="canvas"` for large series. Both are loaded on the first render of
53
+ * a chart that needs them — Recharts as one chunk, each `@nivo/*` package as
54
+ * its own — so importing `Chart` costs nothing until a chart is drawn, and a
55
+ * screen that draws a bar chart never fetches Nivo.
56
+ * Colours, fonts, axes, grid, tooltip, legend and the empty, loading and
57
+ * error states all come from cortena-design tokens; a consumer passes data
58
+ * and, optionally, a `config` of labels.
59
+ *
60
+ * `heatmap` takes either the Nivo series shape or a categorical
61
+ * {@link ChartMatrix} — `{ rows, columns, values }` — for the correlation and
62
+ * confusion matrices that are already in that form.
63
+ *
64
+ * `testMode` gives the drawing area a 600×300 floor so a chart still draws
65
+ * where the layout gives it no size; see {@link ChartContainerProps.testMode}
66
+ * and README.md, "Charts in tests".
67
+ */
68
+ declare function Chart<T extends ChartType>({ type, data, config, renderer, indexBy, keys, stacked, scale, legend, grid, tooltip, labels, valueFormatter, from, to, loading, error, emptyMessage, className, height, ...props }: ChartProps<T>): React.JSX.Element;
69
+ //#endregion
70
+ export { Chart };
71
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1,167 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../../lib/cn.js";
4
+ import { RechartsChartLazy, resetRechartsChunks } from "./recharts-lazy.js";
5
+ import { ChartContainer, ChartEmpty, ChartError, ChartLoading } from "./container.js";
6
+ import { configFor, isEmptyData, isMatrix, isSeriesArray, toRows, toSlices } from "./data.js";
7
+ import { NivoChartLazy, resetNivoChunks } from "./nivo-lazy.js";
8
+ import { chartEngine } from "./types.js";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import * as React from "react";
11
+ //#region src/components/chart/chart.tsx
12
+ function seriesKeys(type, data, indexBy, keys) {
13
+ switch (type) {
14
+ case "bar":
15
+ case "line":
16
+ case "area":
17
+ case "radar": return toRows(data, indexBy, keys).keys;
18
+ case "pie":
19
+ case "donut":
20
+ case "funnel": return toSlices(data).map((s) => s.id);
21
+ case "heatmap":
22
+ if (isMatrix(data)) return data.rows.map(String);
23
+ return isSeriesArray(data) ? data.map((s) => String(s.id)) : [];
24
+ case "scatter":
25
+ case "scatterplot": return isSeriesArray(data) ? data.map((s) => String(s.id)) : [];
26
+ case "treemap":
27
+ case "sunburst": return (data.children ?? []).map((c) => String(c.id ?? c.name ?? ""));
28
+ case "calendar": return [];
29
+ }
30
+ }
31
+ /**
32
+ * Catches a Nivo chunk that failed to load. Recovering takes two things,
33
+ * because `React.lazy` memoises a rejection for the life of the page: fresh
34
+ * lazy components ({@link resetNivoChunks}) and a boundary that leaves its
35
+ * failed state. `resetKey` does the second on its own when the chart changes,
36
+ * and the fallback gets a `retry` that does both.
37
+ */
38
+ var ChunkBoundary = class extends React.Component {
39
+ state = {
40
+ failed: false,
41
+ key: this.props.resetKey
42
+ };
43
+ static getDerivedStateFromError() {
44
+ return { failed: true };
45
+ }
46
+ static getDerivedStateFromProps(props, state) {
47
+ return props.resetKey === state.key ? null : {
48
+ failed: false,
49
+ key: props.resetKey
50
+ };
51
+ }
52
+ retry = () => {
53
+ resetNivoChunks();
54
+ resetRechartsChunks();
55
+ this.setState({ failed: false });
56
+ };
57
+ render() {
58
+ return this.state.failed ? this.props.fallback(this.retry) : this.props.children;
59
+ }
60
+ };
61
+ /** Shown when an engine chunk could not be fetched, with a way back. */
62
+ function chunkFallback(retry) {
63
+ return /* @__PURE__ */ jsxs(ChartError, { children: [
64
+ "Chart could not be loaded.",
65
+ " ",
66
+ /* @__PURE__ */ jsx("button", {
67
+ type: "button",
68
+ "data-slot": "chart-retry",
69
+ onClick: retry,
70
+ className: "underline underline-offset-2",
71
+ children: "Retry"
72
+ })
73
+ ] });
74
+ }
75
+ /**
76
+ * Chart — one component for every chart type the fleet draws.
77
+ *
78
+ * `type` picks the engine: Recharts for bar, line, area, pie, donut, scatter,
79
+ * radar and funnel; Nivo for heatmap, calendar, treemap and sunburst, with
80
+ * `renderer="canvas"` for large series. Both are loaded on the first render of
81
+ * a chart that needs them — Recharts as one chunk, each `@nivo/*` package as
82
+ * its own — so importing `Chart` costs nothing until a chart is drawn, and a
83
+ * screen that draws a bar chart never fetches Nivo.
84
+ * Colours, fonts, axes, grid, tooltip, legend and the empty, loading and
85
+ * error states all come from cortena-design tokens; a consumer passes data
86
+ * and, optionally, a `config` of labels.
87
+ *
88
+ * `heatmap` takes either the Nivo series shape or a categorical
89
+ * {@link ChartMatrix} — `{ rows, columns, values }` — for the correlation and
90
+ * confusion matrices that are already in that form.
91
+ *
92
+ * `testMode` gives the drawing area a 600×300 floor so a chart still draws
93
+ * where the layout gives it no size; see {@link ChartContainerProps.testMode}
94
+ * and README.md, "Charts in tests".
95
+ */
96
+ function Chart({ type, data, config, renderer = "svg", indexBy, keys, stacked, scale = "sequential", legend, grid = true, tooltip = true, labels = "percent", valueFormatter, from, to, loading, error, emptyMessage, className, height, ...props }) {
97
+ const engine = chartEngine(type);
98
+ const empty = isEmptyData(data);
99
+ const fullConfig = React.useMemo(() => configFor(empty ? [] : seriesKeys(type, data, indexBy, keys), config), [
100
+ type,
101
+ data,
102
+ indexBy,
103
+ keys,
104
+ config,
105
+ empty
106
+ ]);
107
+ const showLegend = legend ?? Object.keys(fullConfig).length > 1;
108
+ const errorText = error instanceof Error ? error.message : error;
109
+ let body;
110
+ let responsive = false;
111
+ if (loading) body = /* @__PURE__ */ jsx(ChartLoading, {});
112
+ else if (errorText) body = /* @__PURE__ */ jsx(ChartError, { children: errorText });
113
+ else if (empty) body = /* @__PURE__ */ jsx(ChartEmpty, { children: emptyMessage });
114
+ else if (engine === "nivo") body = /* @__PURE__ */ jsx(ChunkBoundary, {
115
+ resetKey: `${type}|${renderer}`,
116
+ fallback: chunkFallback,
117
+ children: /* @__PURE__ */ jsx(React.Suspense, {
118
+ fallback: /* @__PURE__ */ jsx(ChartLoading, {}),
119
+ children: /* @__PURE__ */ jsx(NivoChartLazy, {
120
+ type,
121
+ data,
122
+ config: fullConfig,
123
+ renderer,
124
+ scale,
125
+ legend: showLegend,
126
+ valueFormatter,
127
+ from,
128
+ to
129
+ })
130
+ })
131
+ });
132
+ else {
133
+ responsive = true;
134
+ body = /* @__PURE__ */ jsx(ChunkBoundary, {
135
+ resetKey: type,
136
+ fallback: chunkFallback,
137
+ children: /* @__PURE__ */ jsx(RechartsChartLazy, {
138
+ type,
139
+ data,
140
+ config: fullConfig,
141
+ indexBy,
142
+ keys,
143
+ stacked,
144
+ legend: showLegend,
145
+ grid,
146
+ tooltip,
147
+ labels,
148
+ valueFormatter
149
+ })
150
+ });
151
+ }
152
+ return /* @__PURE__ */ jsx(ChartContainer, {
153
+ "data-type": type,
154
+ "data-engine": engine,
155
+ "data-renderer": engine === "nivo" ? renderer : "svg",
156
+ config: fullConfig,
157
+ height,
158
+ responsive,
159
+ className: cn(className),
160
+ ...props,
161
+ children: body
162
+ });
163
+ }
164
+ //#endregion
165
+ export { Chart };
166
+
167
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","names":[],"sources":["../../../src/components/chart/chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/cn\";\nimport { ChartContainer, ChartEmpty, ChartError, ChartLoading, type ChartContainerProps } from \"./container\";\nimport { configFor, isEmptyData, isMatrix, isSeriesArray, toRows, toSlices } from \"./data\";\nimport type { NivoType } from \"./nivo-charts\";\nimport { NivoChartLazy, resetNivoChunks } from \"./nivo-lazy\";\nimport type { RechartsType } from \"./recharts-charts\";\nimport { RechartsChartLazy, resetRechartsChunks } from \"./recharts-lazy\";\nimport {\n chartEngine,\n type ChartConfig,\n type ChartDataFor,\n type ChartLabels,\n type ChartMatrix,\n type ChartRenderer,\n type ChartRow,\n type ChartScale,\n type ChartSeries,\n type ChartSlice,\n type ChartTree,\n type ChartType,\n} from \"./types\";\n\nexport interface ChartProps<T extends ChartType = ChartType>\n extends Omit<ChartContainerProps, \"children\" | \"config\" | \"responsive\"> {\n /** Which chart to draw; the package picks the engine. See {@link ChartType} for the data shape per type. */\n type: T;\n /** The data, in the shape documented on {@link ChartType}. */\n data: ChartDataFor<T>;\n /** Series presentation keyed by series id; colours default to `--ds-viz-1..n` in order. */\n config?: ChartConfig;\n /** Nivo renderer; `canvas` for large series. Ignored by the Recharts types and by sunburst. */\n renderer?: ChartRenderer;\n /** Category key for row data (bar, line, area, radar); inferred as the first string field. */\n indexBy?: string;\n /** Series keys for row data; inferred as every numeric field. */\n keys?: string[];\n /** Stack bars and areas instead of grouping them. */\n stacked?: boolean;\n /** Continuous scale for heatmap and calendar. Default sequential. */\n scale?: ChartScale;\n /** Show a legend. Default: when there is more than one series. */\n legend?: boolean;\n /** Draw grid lines (cartesian and radar types). Default true. */\n grid?: boolean;\n /** Show a tooltip on hover. Default true. */\n tooltip?: boolean;\n /**\n * Per-arc labels for `pie` and `donut`; ignored by every other type. Default\n * `percent`, which is what the reader almost always wants and what cortenaweb's\n * donuts showed before this package existed. See {@link ChartLabels}.\n */\n labels?: ChartLabels;\n /** Format values in axes, tooltips and labels. */\n valueFormatter?: (value: number) => string;\n /** Calendar range (ISO dates); defaults to the data's extent. */\n from?: string;\n to?: string;\n /** Render the loading skeleton instead of the data. */\n loading?: boolean;\n /** Render the error state with this message instead of the data. */\n error?: React.ReactNode | Error | null;\n /** Content of the empty state. Default \"No data\". */\n emptyMessage?: React.ReactNode;\n}\n\nfunction seriesKeys(type: ChartType, data: unknown, indexBy?: string, keys?: string[]): string[] {\n switch (type) {\n case \"bar\":\n case \"line\":\n case \"area\":\n case \"radar\":\n return toRows(data as ChartRow[] | ChartSeries[], indexBy, keys).keys;\n case \"pie\":\n case \"donut\":\n case \"funnel\":\n return toSlices(data as ChartSlice[]).map((s) => s.id);\n case \"heatmap\":\n if (isMatrix(data)) return data.rows.map(String);\n return isSeriesArray(data) ? data.map((s) => String(s.id)) : [];\n case \"scatter\":\n case \"scatterplot\":\n return isSeriesArray(data) ? data.map((s) => String(s.id)) : [];\n case \"treemap\":\n case \"sunburst\":\n return ((data as ChartTree).children ?? []).map((c) => String(c.id ?? c.name ?? \"\"));\n case \"calendar\":\n return [];\n }\n}\n\ninterface ChunkBoundaryProps {\n children: React.ReactNode;\n /** Changing it clears a previous failure and renders the children again. */\n resetKey: string;\n fallback: (retry: () => void) => React.ReactNode;\n}\n\n/**\n * Catches a Nivo chunk that failed to load. Recovering takes two things,\n * because `React.lazy` memoises a rejection for the life of the page: fresh\n * lazy components ({@link resetNivoChunks}) and a boundary that leaves its\n * failed state. `resetKey` does the second on its own when the chart changes,\n * and the fallback gets a `retry` that does both.\n */\nclass ChunkBoundary extends React.Component<ChunkBoundaryProps, { failed: boolean; key: string }> {\n state = { failed: false, key: this.props.resetKey };\n static getDerivedStateFromError() {\n return { failed: true };\n }\n static getDerivedStateFromProps(props: ChunkBoundaryProps, state: { failed: boolean; key: string }) {\n return props.resetKey === state.key ? null : { failed: false, key: props.resetKey };\n }\n retry = () => {\n resetNivoChunks();\n resetRechartsChunks();\n this.setState({ failed: false });\n };\n render() {\n return this.state.failed ? this.props.fallback(this.retry) : this.props.children;\n }\n}\n\n/** Shown when an engine chunk could not be fetched, with a way back. */\nfunction chunkFallback(retry: () => void): React.ReactNode {\n return (\n <ChartError>\n Chart could not be loaded.{\" \"}\n <button type=\"button\" data-slot=\"chart-retry\" onClick={retry} className=\"underline underline-offset-2\">\n Retry\n </button>\n </ChartError>\n );\n}\n\n/**\n * Chart — one component for every chart type the fleet draws.\n *\n * `type` picks the engine: Recharts for bar, line, area, pie, donut, scatter,\n * radar and funnel; Nivo for heatmap, calendar, treemap and sunburst, with\n * `renderer=\"canvas\"` for large series. Both are loaded on the first render of\n * a chart that needs them — Recharts as one chunk, each `@nivo/*` package as\n * its own — so importing `Chart` costs nothing until a chart is drawn, and a\n * screen that draws a bar chart never fetches Nivo.\n * Colours, fonts, axes, grid, tooltip, legend and the empty, loading and\n * error states all come from cortena-design tokens; a consumer passes data\n * and, optionally, a `config` of labels.\n *\n * `heatmap` takes either the Nivo series shape or a categorical\n * {@link ChartMatrix} — `{ rows, columns, values }` — for the correlation and\n * confusion matrices that are already in that form.\n *\n * `testMode` gives the drawing area a 600×300 floor so a chart still draws\n * where the layout gives it no size; see {@link ChartContainerProps.testMode}\n * and README.md, \"Charts in tests\".\n */\nfunction Chart<T extends ChartType>({\n type,\n data,\n config,\n renderer = \"svg\",\n indexBy,\n keys,\n stacked,\n scale = \"sequential\",\n legend,\n grid = true,\n tooltip = true,\n labels = \"percent\",\n valueFormatter,\n from,\n to,\n loading,\n error,\n emptyMessage,\n className,\n height,\n ...props\n}: ChartProps<T>) {\n const engine = chartEngine(type);\n const empty = isEmptyData(data);\n const fullConfig = React.useMemo(\n () => configFor(empty ? [] : seriesKeys(type, data, indexBy, keys), config),\n [type, data, indexBy, keys, config, empty],\n );\n const showLegend = legend ?? Object.keys(fullConfig).length > 1;\n const errorText = error instanceof Error ? error.message : error;\n\n let body: React.ReactNode;\n let responsive = false;\n if (loading) body = <ChartLoading />;\n else if (errorText) body = <ChartError>{errorText}</ChartError>;\n else if (empty) body = <ChartEmpty>{emptyMessage}</ChartEmpty>;\n else if (engine === \"nivo\") {\n body = (\n <ChunkBoundary resetKey={`${type}|${renderer}`} fallback={chunkFallback}>\n <React.Suspense fallback={<ChartLoading />}>\n <NivoChartLazy\n type={type as NivoType}\n data={data}\n config={fullConfig}\n renderer={renderer}\n scale={scale}\n legend={showLegend}\n valueFormatter={valueFormatter}\n from={from}\n to={to}\n />\n </React.Suspense>\n </ChunkBoundary>\n );\n } else {\n responsive = true;\n body = (\n <ChunkBoundary resetKey={type} fallback={chunkFallback}>\n <RechartsChartLazy\n type={type as RechartsType}\n data={data}\n config={fullConfig}\n indexBy={indexBy}\n keys={keys}\n stacked={stacked}\n legend={showLegend}\n grid={grid}\n tooltip={tooltip}\n labels={labels}\n valueFormatter={valueFormatter}\n />\n </ChunkBoundary>\n );\n }\n\n return (\n <ChartContainer\n data-type={type}\n data-engine={engine}\n data-renderer={engine === \"nivo\" ? renderer : \"svg\"}\n config={fullConfig}\n height={height}\n responsive={responsive}\n className={cn(className)}\n {...props}\n >\n {body}\n </ChartContainer>\n );\n}\n\nexport { Chart };\n"],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import { ChartConfig } from "./types.js";
3
+ import * as React from "react";
4
+ import { LegendPayload, TooltipContentProps } from "recharts";
5
+ //#region src/components/chart/container.d.ts
6
+ interface ChartContextValue {
7
+ config: ChartConfig;
8
+ /** The container element, so token resolution can honour a nested theme scope. */
9
+ element: HTMLDivElement | null;
10
+ }
11
+ /** The nearest ChartContainer's config and element; null outside one. */
12
+ export declare function useChart(): ChartContextValue | null;
13
+ /**
14
+ * Resolve the colour a series key paints with: `config[key].color` when set,
15
+ * otherwise `var(--ds-viz-N)` by the key's position in the config (or the
16
+ * `index` given). Recharts consumers reference it as `var(--color-<key>)`,
17
+ * which ChartContainer defines on its element.
18
+ */
19
+ export declare function seriesColor(config: ChartConfig | undefined, key: string, index?: number): string;
20
+ export interface ChartContainerProps extends Omit<React.ComponentProps<"div">, "children"> {
21
+ /** Series presentation; colours default to `--ds-viz-1..n` in key order. */
22
+ config?: ChartConfig;
23
+ /** Height of the drawing area; width is always 100% of the parent. Default 300. */
24
+ height?: number | string;
25
+ /**
26
+ * Wrap children in Recharts' ResponsiveContainer (default). Nivo's
27
+ * `Responsive*` components size themselves, so the Nivo renderers pass
28
+ * `responsive={false}`.
29
+ */
30
+ responsive?: boolean;
31
+ /**
32
+ * Give the drawing area a floor of 600×300 so it draws where the layout
33
+ * gives it none.
34
+ *
35
+ * Both engines size themselves from the parent box. Under jsdom nothing has
36
+ * layout — every element measures 0×0 — so a page test that renders a screen
37
+ * containing a Chart gets an empty `<div>` and can assert nothing about it.
38
+ * `testMode` sets `min-width` / `min-height` on the container and hands the
39
+ * same floor to Recharts' ResponsiveContainer, so the chart draws at
40
+ * 600×300. It is a floor, not a fixed size: a parent that *does* give the
41
+ * chart 900px still gets 900px, so a screenshot test is unaffected.
42
+ */
43
+ testMode?: boolean;
44
+ children: React.ReactNode;
45
+ }
46
+ /**
47
+ * ChartContainer — the sized, token-styled surface every chart draws in.
48
+ *
49
+ * It defines `--color-<key>` for each config key (so Recharts parts can say
50
+ * `fill="var(--color-revenue)"`) and styles Recharts' axis, grid, tick and
51
+ * cursor classes from tokens with a caption-sm floor for text, so a custom
52
+ * chart composed inside it needs no local colours or fonts.
53
+ */
54
+ declare function ChartContainer({ config, height, responsive, testMode, className, style, children, ...props }: ChartContainerProps): React.JSX.Element;
55
+ /** "No data" placeholder; rendered by Chart when the data is empty. */
56
+ declare function ChartEmpty({ children, ...props }: React.ComponentProps<"div">): React.JSX.Element;
57
+ /** Error placeholder; rendered by Chart for an `error` prop or a failed Nivo chunk. */
58
+ declare function ChartError({ className, children, ...props }: React.ComponentProps<"div">): React.JSX.Element;
59
+ /** Loading placeholder: a skeleton the size of the drawing area, shown while a Nivo chunk loads. */
60
+ declare function ChartLoading({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
61
+ export interface ChartTooltipContentProps extends Partial<Pick<TooltipContentProps, "active" | "payload" | "label">> {
62
+ className?: string;
63
+ /** Hide the series label column. */
64
+ hideLabel?: boolean;
65
+ /** Hide the colour swatch. */
66
+ hideIndicator?: boolean;
67
+ /** Format a value; defaults to `toLocaleString`. */
68
+ formatter?: (value: number | string, name: string) => React.ReactNode;
69
+ /** Format the header (the category). */
70
+ labelFormatter?: (label: React.ReactNode) => React.ReactNode;
71
+ }
72
+ /**
73
+ * ChartTooltipContent — the popover body for Recharts' Tooltip, styled like
74
+ * the package Tooltip on the popover tokens. Pass as `content` to
75
+ * ChartTooltip; reads series labels and colours from the ChartContainer config.
76
+ */
77
+ declare function ChartTooltipContent({ active, payload, label, className, hideLabel, hideIndicator, formatter, labelFormatter }: ChartTooltipContentProps): React.JSX.Element | null;
78
+ export interface ChartLegendContentProps {
79
+ payload?: readonly LegendPayload[];
80
+ verticalAlign?: "top" | "bottom" | "middle";
81
+ className?: string;
82
+ hideIcon?: boolean;
83
+ }
84
+ /** ChartLegendContent — Recharts' legend on tokens; reads labels from the config. */
85
+ declare function ChartLegendContent({ payload, verticalAlign, className, hideIcon }: ChartLegendContentProps): React.JSX.Element | null;
86
+ //#endregion
87
+ export { ChartContainer, ChartEmpty, ChartError, ChartLegendContent, ChartLoading, ChartTooltipContent };
88
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1,189 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../../lib/cn.js";
4
+ import { Skeleton } from "../skeleton.js";
5
+ import { RechartsResponsive } from "./recharts-lazy.js";
6
+ import { vizVar } from "./tokens.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import * as React from "react";
9
+ //#region src/components/chart/container.tsx
10
+ const ChartContext = /* @__PURE__ */ React.createContext(null);
11
+ /** The nearest ChartContainer's config and element; null outside one. */
12
+ function useChart() {
13
+ return React.useContext(ChartContext);
14
+ }
15
+ /**
16
+ * Resolve the colour a series key paints with: `config[key].color` when set,
17
+ * otherwise `var(--ds-viz-N)` by the key's position in the config (or the
18
+ * `index` given). Recharts consumers reference it as `var(--color-<key>)`,
19
+ * which ChartContainer defines on its element.
20
+ */
21
+ function seriesColor(config, key, index) {
22
+ const entry = config?.[key];
23
+ if (entry?.color) return entry.color;
24
+ const position = (config ? Object.keys(config) : []).indexOf(key);
25
+ return vizVar(position >= 0 ? position : index ?? 0);
26
+ }
27
+ /** The box `testMode` falls back to when the layout gives the chart none. */
28
+ const TEST_WIDTH = 600;
29
+ const TEST_HEIGHT = 300;
30
+ /**
31
+ * ChartContainer — the sized, token-styled surface every chart draws in.
32
+ *
33
+ * It defines `--color-<key>` for each config key (so Recharts parts can say
34
+ * `fill="var(--color-revenue)"`) and styles Recharts' axis, grid, tick and
35
+ * cursor classes from tokens with a caption-sm floor for text, so a custom
36
+ * chart composed inside it needs no local colours or fonts.
37
+ */
38
+ function ChartContainer({ config = {}, height = 300, responsive = true, testMode = false, className, style, children, ...props }) {
39
+ const [element, setElement] = React.useState(null);
40
+ const vars = React.useMemo(() => {
41
+ const out = {};
42
+ for (const key of Object.keys(config)) out[`--color-${key}`] = seriesColor(config, key);
43
+ return out;
44
+ }, [config]);
45
+ const ctx = React.useMemo(() => ({
46
+ config,
47
+ element
48
+ }), [config, element]);
49
+ return /* @__PURE__ */ jsx(ChartContext.Provider, {
50
+ value: ctx,
51
+ children: /* @__PURE__ */ jsx("div", {
52
+ ref: setElement,
53
+ "data-slot": "chart",
54
+ "data-test-mode": testMode ? "" : void 0,
55
+ className: cn("relative w-full min-w-0 overflow-hidden text-[length:var(--ds-text-caption-sm)] text-[color:var(--ds-foreground)]", responsive ? "flex justify-center" : "block [&>div]:h-full [&>div]:w-full", "[&_.recharts-cartesian-axis-tick-value]:fill-[var(--ds-muted-foreground)]", "[&_.recharts-polar-angle-axis-tick-value]:fill-[var(--ds-muted-foreground)]", "[&_.recharts-polar-radius-axis-tick-value]:fill-[var(--ds-muted-foreground)]", "[&_.recharts-cartesian-grid-horizontal_line]:stroke-[var(--ds-border-subtle)]", "[&_.recharts-cartesian-grid-vertical_line]:stroke-[var(--ds-border-subtle)]", "[&_.recharts-polar-grid-angle_line]:stroke-[var(--ds-border-subtle)]", "[&_.recharts-polar-grid-concentric-polygon]:stroke-[var(--ds-border-subtle)]", "[&_.recharts-polar-grid-concentric-circle]:stroke-[var(--ds-border-subtle)]", "[&_.recharts-cartesian-axis-line]:stroke-[var(--ds-border)]", "[&_.recharts-cartesian-axis-tick-line]:stroke-[var(--ds-border)]", "[&_.recharts-radial-bar-background-sector]:fill-[var(--ds-muted)]", "[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-[var(--ds-hover)]", "[&_.recharts-curve.recharts-tooltip-cursor]:stroke-[var(--ds-border-strong)]", "[&_.recharts-reference-line_line]:stroke-[var(--ds-border-strong)]", "[&_.recharts-pie-sector_.recharts-sector]:stroke-[var(--ds-card)]", "[&_.recharts-funnel-trapezoid_.recharts-trapezoid]:stroke-[var(--ds-card)]", "[&_.recharts-layer]:outline-hidden [&_.recharts-surface]:outline-hidden [&_.recharts-sector]:outline-hidden", "[&_text]:font-[family-name:var(--ds-font-body)]", className),
56
+ style: {
57
+ height,
58
+ ...testMode ? {
59
+ minWidth: TEST_WIDTH,
60
+ minHeight: TEST_HEIGHT
61
+ } : null,
62
+ ...vars,
63
+ ...style
64
+ },
65
+ ...props,
66
+ children: responsive ? /* @__PURE__ */ jsx(React.Suspense, {
67
+ fallback: /* @__PURE__ */ jsx(ChartLoading, {}),
68
+ children: /* @__PURE__ */ jsx(RechartsResponsive, {
69
+ width: "100%",
70
+ height: "100%",
71
+ minWidth: testMode ? TEST_WIDTH : void 0,
72
+ minHeight: testMode ? TEST_HEIGHT : void 0,
73
+ children
74
+ })
75
+ }) : children
76
+ })
77
+ });
78
+ }
79
+ function ChartState({ className, ...props }) {
80
+ return /* @__PURE__ */ jsx("div", {
81
+ className: cn("flex h-full w-full items-center justify-center rounded-[var(--ds-radius-md)] border border-dashed border-[var(--ds-border-subtle)]", "text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]", className),
82
+ ...props
83
+ });
84
+ }
85
+ /** "No data" placeholder; rendered by Chart when the data is empty. */
86
+ function ChartEmpty({ children = "No data", ...props }) {
87
+ return /* @__PURE__ */ jsx(ChartState, {
88
+ "data-slot": "chart-empty",
89
+ role: "status",
90
+ ...props,
91
+ children
92
+ });
93
+ }
94
+ /** Error placeholder; rendered by Chart for an `error` prop or a failed Nivo chunk. */
95
+ function ChartError({ className, children = "Chart could not be rendered", ...props }) {
96
+ return /* @__PURE__ */ jsx(ChartState, {
97
+ "data-slot": "chart-error",
98
+ role: "alert",
99
+ className: cn("border-[var(--ds-destructive)] text-[color:var(--ds-destructive)]", className),
100
+ ...props,
101
+ children
102
+ });
103
+ }
104
+ /** Loading placeholder: a skeleton the size of the drawing area, shown while a Nivo chunk loads. */
105
+ function ChartLoading({ className, ...props }) {
106
+ return /* @__PURE__ */ jsx("div", {
107
+ "data-slot": "chart-loading",
108
+ className: cn("h-full w-full", className),
109
+ ...props,
110
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "h-full w-full rounded-[var(--ds-radius-md)]" })
111
+ });
112
+ }
113
+ function formatValue(value, formatter, name = "") {
114
+ if (formatter && (typeof value === "number" || typeof value === "string")) return formatter(value, name);
115
+ if (typeof value === "number") return value.toLocaleString();
116
+ if (value == null) return "";
117
+ return String(value);
118
+ }
119
+ /**
120
+ * ChartTooltipContent — the popover body for Recharts' Tooltip, styled like
121
+ * the package Tooltip on the popover tokens. Pass as `content` to
122
+ * ChartTooltip; reads series labels and colours from the ChartContainer config.
123
+ */
124
+ function ChartTooltipContent({ active, payload, label, className, hideLabel, hideIndicator, formatter, labelFormatter }) {
125
+ const chart = useChart();
126
+ if (!active || !payload?.length) return null;
127
+ const heading = labelFormatter ? labelFormatter(label) : label;
128
+ return /* @__PURE__ */ jsxs("div", {
129
+ "data-slot": "chart-tooltip",
130
+ className: cn("grid min-w-32 gap-1.5 rounded-[var(--ds-radius-md)] border border-[var(--ds-border-subtle)] bg-[var(--ds-popover)] px-2.5 py-1.5", "text-[length:var(--ds-text-caption)] text-[color:var(--ds-popover-foreground)] shadow-[var(--ds-shadow-md)]", className),
131
+ children: [!hideLabel && heading != null && heading !== "" ? /* @__PURE__ */ jsx("div", {
132
+ className: "font-medium",
133
+ children: heading
134
+ }) : null, /* @__PURE__ */ jsx("div", {
135
+ className: "grid gap-1",
136
+ children: payload.map((item, i) => {
137
+ const key = String(item.dataKey ?? item.name ?? i);
138
+ const entry = chart?.config[key];
139
+ const colour = item.color ?? item.fill ?? item.stroke ?? `var(--color-${key})`;
140
+ const name = entry?.label ?? item.name ?? key;
141
+ return /* @__PURE__ */ jsxs("div", {
142
+ className: "flex items-center gap-2",
143
+ children: [
144
+ hideIndicator ? null : /* @__PURE__ */ jsx("span", {
145
+ "aria-hidden": true,
146
+ "data-slot": "chart-tooltip-indicator",
147
+ className: "size-2 shrink-0 rounded-[var(--ds-radius-sm)]",
148
+ style: { background: colour }
149
+ }),
150
+ /* @__PURE__ */ jsx("span", {
151
+ className: "flex-1 text-[color:var(--ds-muted-foreground)]",
152
+ children: name
153
+ }),
154
+ /* @__PURE__ */ jsx("span", {
155
+ className: "font-[family-name:var(--ds-font-mono)] font-medium tabular-nums",
156
+ children: formatValue(item.value, formatter, String(name))
157
+ })
158
+ ]
159
+ }, key);
160
+ })
161
+ })]
162
+ });
163
+ }
164
+ /** ChartLegendContent — Recharts' legend on tokens; reads labels from the config. */
165
+ function ChartLegendContent({ payload, verticalAlign = "bottom", className, hideIcon }) {
166
+ const chart = useChart();
167
+ if (!payload?.length) return null;
168
+ return /* @__PURE__ */ jsx("div", {
169
+ "data-slot": "chart-legend",
170
+ className: cn("flex flex-wrap items-center justify-center gap-x-4 gap-y-1", "text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]", verticalAlign === "top" ? "pb-3" : "pt-3", className),
171
+ children: payload.map((item, i) => {
172
+ const key = String(item.dataKey ?? item.value ?? i);
173
+ const entry = chart?.config[key];
174
+ const Icon = entry?.icon;
175
+ return /* @__PURE__ */ jsxs("div", {
176
+ className: "flex items-center gap-1.5",
177
+ children: [hideIcon ? null : Icon ? /* @__PURE__ */ jsx(Icon, {}) : /* @__PURE__ */ jsx("span", {
178
+ "aria-hidden": true,
179
+ className: "size-2 shrink-0 rounded-[var(--ds-radius-sm)]",
180
+ style: { background: item.color ?? `var(--color-${key})` }
181
+ }), entry?.label ?? item.value]
182
+ }, key);
183
+ })
184
+ });
185
+ }
186
+ //#endregion
187
+ export { ChartContainer, ChartContext, ChartEmpty, ChartError, ChartLegendContent, ChartLoading, ChartTooltipContent, seriesColor, useChart };
188
+
189
+ //# sourceMappingURL=container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.js","names":[],"sources":["../../../src/components/chart/container.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n// Types only. The two Recharts *values* this file used to reach for — `Tooltip`\n// and `Legend` — are in `recharts-parts.tsx`, so that nothing on the eager path\n// imports the engine; see the note there.\nimport type { LegendPayload, TooltipContentProps } from \"recharts\";\nimport { RechartsResponsive } from \"./recharts-lazy\";\nimport { cn } from \"@/lib/cn\";\nimport { Skeleton } from \"@/components/skeleton\";\nimport { vizVar } from \"./tokens\";\nimport type { ChartConfig } from \"./types\";\n\n/* ── context ─────────────────────────────────────────────────────────────── */\n\ninterface ChartContextValue {\n config: ChartConfig;\n /** The container element, so token resolution can honour a nested theme scope. */\n element: HTMLDivElement | null;\n}\n\nconst ChartContext = /* @__PURE__ */ React.createContext<ChartContextValue | null>(null);\n\n/** The nearest ChartContainer's config and element; null outside one. */\nexport function useChart(): ChartContextValue | null {\n return React.useContext(ChartContext);\n}\n\n/**\n * Resolve the colour a series key paints with: `config[key].color` when set,\n * otherwise `var(--ds-viz-N)` by the key's position in the config (or the\n * `index` given). Recharts consumers reference it as `var(--color-<key>)`,\n * which ChartContainer defines on its element.\n */\nexport function seriesColor(config: ChartConfig | undefined, key: string, index?: number): string {\n const entry = config?.[key];\n if (entry?.color) return entry.color;\n const keys = config ? Object.keys(config) : [];\n const position = keys.indexOf(key);\n return vizVar(position >= 0 ? position : (index ?? 0));\n}\n\n/* ── container ───────────────────────────────────────────────────────────── */\n\nexport interface ChartContainerProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n /** Series presentation; colours default to `--ds-viz-1..n` in key order. */\n config?: ChartConfig;\n /** Height of the drawing area; width is always 100% of the parent. Default 300. */\n height?: number | string;\n /**\n * Wrap children in Recharts' ResponsiveContainer (default). Nivo's\n * `Responsive*` components size themselves, so the Nivo renderers pass\n * `responsive={false}`.\n */\n responsive?: boolean;\n /**\n * Give the drawing area a floor of 600×300 so it draws where the layout\n * gives it none.\n *\n * Both engines size themselves from the parent box. Under jsdom nothing has\n * layout — every element measures 0×0 — so a page test that renders a screen\n * containing a Chart gets an empty `<div>` and can assert nothing about it.\n * `testMode` sets `min-width` / `min-height` on the container and hands the\n * same floor to Recharts' ResponsiveContainer, so the chart draws at\n * 600×300. It is a floor, not a fixed size: a parent that *does* give the\n * chart 900px still gets 900px, so a screenshot test is unaffected.\n */\n testMode?: boolean;\n children: React.ReactNode;\n}\n\n/** The box `testMode` falls back to when the layout gives the chart none. */\nconst TEST_WIDTH = 600;\nconst TEST_HEIGHT = 300;\n\n/**\n * ChartContainer — the sized, token-styled surface every chart draws in.\n *\n * It defines `--color-<key>` for each config key (so Recharts parts can say\n * `fill=\"var(--color-revenue)\"`) and styles Recharts' axis, grid, tick and\n * cursor classes from tokens with a caption-sm floor for text, so a custom\n * chart composed inside it needs no local colours or fonts.\n */\nfunction ChartContainer({\n config = {},\n height = 300,\n responsive = true,\n testMode = false,\n className,\n style,\n children,\n ...props\n}: ChartContainerProps) {\n const [element, setElement] = React.useState<HTMLDivElement | null>(null);\n const vars = React.useMemo(() => {\n const out: Record<string, string> = {};\n for (const key of Object.keys(config)) out[`--color-${key}`] = seriesColor(config, key);\n return out;\n }, [config]);\n const ctx = React.useMemo(() => ({ config, element }), [config, element]);\n\n return (\n <ChartContext.Provider value={ctx}>\n <div\n ref={setElement}\n data-slot=\"chart\"\n data-test-mode={testMode ? \"\" : undefined}\n className={cn(\n \"relative w-full min-w-0 overflow-hidden text-[length:var(--ds-text-caption-sm)] text-[color:var(--ds-foreground)]\",\n responsive ? \"flex justify-center\" : \"block [&>div]:h-full [&>div]:w-full\",\n \"[&_.recharts-cartesian-axis-tick-value]:fill-[var(--ds-muted-foreground)]\",\n \"[&_.recharts-polar-angle-axis-tick-value]:fill-[var(--ds-muted-foreground)]\",\n \"[&_.recharts-polar-radius-axis-tick-value]:fill-[var(--ds-muted-foreground)]\",\n \"[&_.recharts-cartesian-grid-horizontal_line]:stroke-[var(--ds-border-subtle)]\",\n \"[&_.recharts-cartesian-grid-vertical_line]:stroke-[var(--ds-border-subtle)]\",\n \"[&_.recharts-polar-grid-angle_line]:stroke-[var(--ds-border-subtle)]\",\n \"[&_.recharts-polar-grid-concentric-polygon]:stroke-[var(--ds-border-subtle)]\",\n \"[&_.recharts-polar-grid-concentric-circle]:stroke-[var(--ds-border-subtle)]\",\n \"[&_.recharts-cartesian-axis-line]:stroke-[var(--ds-border)]\",\n \"[&_.recharts-cartesian-axis-tick-line]:stroke-[var(--ds-border)]\",\n \"[&_.recharts-radial-bar-background-sector]:fill-[var(--ds-muted)]\",\n \"[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-[var(--ds-hover)]\",\n \"[&_.recharts-curve.recharts-tooltip-cursor]:stroke-[var(--ds-border-strong)]\",\n \"[&_.recharts-reference-line_line]:stroke-[var(--ds-border-strong)]\",\n \"[&_.recharts-pie-sector_.recharts-sector]:stroke-[var(--ds-card)]\",\n \"[&_.recharts-funnel-trapezoid_.recharts-trapezoid]:stroke-[var(--ds-card)]\",\n \"[&_.recharts-layer]:outline-hidden [&_.recharts-surface]:outline-hidden [&_.recharts-sector]:outline-hidden\",\n \"[&_text]:font-[family-name:var(--ds-font-body)]\",\n className,\n )}\n style={\n {\n height,\n ...(testMode ? { minWidth: TEST_WIDTH, minHeight: TEST_HEIGHT } : null),\n ...vars,\n ...style,\n } as React.CSSProperties\n }\n {...props}\n >\n {responsive ? (\n // Recharts' ResponsiveContainer arrives with the engine chunk, so\n // this suspends on the first chart drawn on the page — and so does\n // whatever it wraps, which is why the skeleton lives here rather than\n // in `Chart`: this is the innermost boundary, so it is the one that\n // catches. A `ChartContainer` used directly, to compose a one-off\n // Recharts chart, gets the same treatment and needs no boundary of\n // its own.\n <React.Suspense fallback={<ChartLoading />}>\n <RechartsResponsive\n width=\"100%\"\n height=\"100%\"\n minWidth={testMode ? TEST_WIDTH : undefined}\n minHeight={testMode ? TEST_HEIGHT : undefined}\n >\n {children as React.ReactElement}\n </RechartsResponsive>\n </React.Suspense>\n ) : (\n children\n )}\n </div>\n </ChartContext.Provider>\n );\n}\n\n/* ── states ──────────────────────────────────────────────────────────────── */\n\nfunction ChartState({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\n \"flex h-full w-full items-center justify-center rounded-[var(--ds-radius-md)] border border-dashed border-[var(--ds-border-subtle)]\",\n \"text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** \"No data\" placeholder; rendered by Chart when the data is empty. */\nfunction ChartEmpty({ children = \"No data\", ...props }: React.ComponentProps<\"div\">) {\n return (\n <ChartState data-slot=\"chart-empty\" role=\"status\" {...props}>\n {children}\n </ChartState>\n );\n}\n\n/** Error placeholder; rendered by Chart for an `error` prop or a failed Nivo chunk. */\nfunction ChartError({ className, children = \"Chart could not be rendered\", ...props }: React.ComponentProps<\"div\">) {\n return (\n <ChartState\n data-slot=\"chart-error\"\n role=\"alert\"\n className={cn(\"border-[var(--ds-destructive)] text-[color:var(--ds-destructive)]\", className)}\n {...props}\n >\n {children}\n </ChartState>\n );\n}\n\n/** Loading placeholder: a skeleton the size of the drawing area, shown while a Nivo chunk loads. */\nfunction ChartLoading({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"chart-loading\" className={cn(\"h-full w-full\", className)} {...props}>\n <Skeleton className=\"h-full w-full rounded-[var(--ds-radius-md)]\" />\n </div>\n );\n}\n\n/* ── tooltip ─────────────────────────────────────────────────────────────── */\n\nexport interface ChartTooltipContentProps\n extends Partial<Pick<TooltipContentProps, \"active\" | \"payload\" | \"label\">> {\n className?: string;\n /** Hide the series label column. */\n hideLabel?: boolean;\n /** Hide the colour swatch. */\n hideIndicator?: boolean;\n /** Format a value; defaults to `toLocaleString`. */\n formatter?: (value: number | string, name: string) => React.ReactNode;\n /** Format the header (the category). */\n labelFormatter?: (label: React.ReactNode) => React.ReactNode;\n}\n\nfunction formatValue(value: unknown, formatter?: ChartTooltipContentProps[\"formatter\"], name = \"\"): React.ReactNode {\n if (formatter && (typeof value === \"number\" || typeof value === \"string\")) return formatter(value, name);\n if (typeof value === \"number\") return value.toLocaleString();\n if (value == null) return \"\";\n return String(value);\n}\n\n/**\n * ChartTooltipContent — the popover body for Recharts' Tooltip, styled like\n * the package Tooltip on the popover tokens. Pass as `content` to\n * ChartTooltip; reads series labels and colours from the ChartContainer config.\n */\nfunction ChartTooltipContent({\n active,\n payload,\n label,\n className,\n hideLabel,\n hideIndicator,\n formatter,\n labelFormatter,\n}: ChartTooltipContentProps) {\n const chart = useChart();\n if (!active || !payload?.length) return null;\n const heading = labelFormatter ? labelFormatter(label) : label;\n return (\n <div\n data-slot=\"chart-tooltip\"\n className={cn(\n \"grid min-w-32 gap-1.5 rounded-[var(--ds-radius-md)] border border-[var(--ds-border-subtle)] bg-[var(--ds-popover)] px-2.5 py-1.5\",\n \"text-[length:var(--ds-text-caption)] text-[color:var(--ds-popover-foreground)] shadow-[var(--ds-shadow-md)]\",\n className,\n )}\n >\n {!hideLabel && heading != null && heading !== \"\" ? (\n <div className=\"font-medium\">{heading}</div>\n ) : null}\n <div className=\"grid gap-1\">\n {payload.map((item, i) => {\n const key = String(item.dataKey ?? item.name ?? i);\n const entry = chart?.config[key];\n const colour = item.color ?? item.fill ?? item.stroke ?? `var(--color-${key})`;\n const name = entry?.label ?? item.name ?? key;\n return (\n <div key={key} className=\"flex items-center gap-2\">\n {hideIndicator ? null : (\n <span\n aria-hidden\n data-slot=\"chart-tooltip-indicator\"\n className=\"size-2 shrink-0 rounded-[var(--ds-radius-sm)]\"\n style={{ background: colour }}\n />\n )}\n <span className=\"flex-1 text-[color:var(--ds-muted-foreground)]\">{name}</span>\n <span className=\"font-[family-name:var(--ds-font-mono)] font-medium tabular-nums\">\n {formatValue(item.value, formatter, String(name))}\n </span>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/* ── legend ──────────────────────────────────────────────────────────────── */\n\nexport interface ChartLegendContentProps {\n payload?: readonly LegendPayload[];\n verticalAlign?: \"top\" | \"bottom\" | \"middle\";\n className?: string;\n hideIcon?: boolean;\n}\n\n/** ChartLegendContent — Recharts' legend on tokens; reads labels from the config. */\nfunction ChartLegendContent({ payload, verticalAlign = \"bottom\", className, hideIcon }: ChartLegendContentProps) {\n const chart = useChart();\n if (!payload?.length) return null;\n return (\n <div\n data-slot=\"chart-legend\"\n className={cn(\n \"flex flex-wrap items-center justify-center gap-x-4 gap-y-1\",\n \"text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className,\n )}\n >\n {payload.map((item, i) => {\n const key = String(item.dataKey ?? item.value ?? i);\n const entry = chart?.config[key];\n const Icon = entry?.icon;\n return (\n <div key={key} className=\"flex items-center gap-1.5\">\n {hideIcon ? null : Icon ? (\n <Icon />\n ) : (\n <span\n aria-hidden\n className=\"size-2 shrink-0 rounded-[var(--ds-radius-sm)]\"\n style={{ background: item.color ?? `var(--color-${key})` }}\n />\n )}\n {entry?.label ?? item.value}\n </div>\n );\n })}\n </div>\n );\n}\n\nexport { ChartContainer, ChartContext, ChartEmpty, ChartError, ChartLoading, ChartTooltipContent, ChartLegendContent };\n"],"mappings":"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"}