@open-mercato/ui 0.6.4-develop.3944.1.4100aa7fbe → 0.6.4-develop.3949.1.adc3d0b3b1

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 (32) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/backend/charts/BarChart.js +19 -76
  3. package/dist/backend/charts/BarChart.js.map +2 -2
  4. package/dist/backend/charts/BarChartImpl.js +91 -0
  5. package/dist/backend/charts/BarChartImpl.js.map +7 -0
  6. package/dist/backend/charts/LineChart.js +18 -91
  7. package/dist/backend/charts/LineChart.js.map +2 -2
  8. package/dist/backend/charts/LineChartImpl.js +112 -0
  9. package/dist/backend/charts/LineChartImpl.js.map +7 -0
  10. package/dist/backend/charts/PieChart.js +17 -62
  11. package/dist/backend/charts/PieChart.js.map +2 -2
  12. package/dist/backend/charts/PieChartImpl.js +76 -0
  13. package/dist/backend/charts/PieChartImpl.js.map +7 -0
  14. package/dist/backend/dashboard/DashboardScreen.js +6 -0
  15. package/dist/backend/dashboard/DashboardScreen.js.map +2 -2
  16. package/dist/backend/dashboard/widgetRegistry.js +18 -2
  17. package/dist/backend/dashboard/widgetRegistry.js.map +2 -2
  18. package/dist/backend/injection/useInjectionDataWidgets.js +12 -2
  19. package/dist/backend/injection/useInjectionDataWidgets.js.map +2 -2
  20. package/package.json +3 -3
  21. package/src/backend/__tests__/lazy-heavy-libraries.test.ts +53 -0
  22. package/src/backend/charts/BarChart.tsx +21 -72
  23. package/src/backend/charts/BarChartImpl.tsx +99 -0
  24. package/src/backend/charts/LineChart.tsx +23 -85
  25. package/src/backend/charts/LineChartImpl.tsx +120 -0
  26. package/src/backend/charts/PieChart.tsx +19 -60
  27. package/src/backend/charts/PieChartImpl.tsx +82 -0
  28. package/src/backend/dashboard/DashboardScreen.tsx +6 -0
  29. package/src/backend/dashboard/__tests__/DashboardScreen.test.tsx +17 -0
  30. package/src/backend/dashboard/__tests__/widgetRegistry.test.ts +60 -0
  31. package/src/backend/dashboard/widgetRegistry.ts +23 -5
  32. package/src/backend/injection/useInjectionDataWidgets.ts +18 -2
@@ -1,3 +1,3 @@
1
1
  Generated lucide registry with 136 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
2
- [build:ui] found 356 entry points
2
+ [build:ui] found 359 entry points
3
3
  [build:ui] built successfully
@@ -1,17 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import {
4
- BarChart as RechartsBarChart,
5
- Bar,
6
- XAxis,
7
- YAxis,
8
- CartesianGrid,
9
- Tooltip,
10
- Legend,
11
- ResponsiveContainer
12
- } from "recharts";
3
+ import dynamic from "next/dynamic";
13
4
  import { Spinner } from "@open-mercato/ui/primitives/spinner";
14
- import { ChartTooltipContent, resolveChartColor } from "./ChartUtils.js";
15
5
  function defaultValueFormatter(value) {
16
6
  if (Math.abs(value) >= 1e6) {
17
7
  return `${(value / 1e6).toFixed(1)}M`;
@@ -21,6 +11,10 @@ function defaultValueFormatter(value) {
21
11
  }
22
12
  return value.toLocaleString(void 0, { maximumFractionDigits: 2 });
23
13
  }
14
+ const BarChartImpl = dynamic(() => import("./BarChartImpl.js"), {
15
+ ssr: false,
16
+ loading: () => /* @__PURE__ */ jsx("div", { className: "flex h-40 sm:h-48 items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { className: "h-6 w-6 text-muted-foreground" }) })
17
+ });
24
18
  function BarChart({
25
19
  title,
26
20
  data,
@@ -37,9 +31,6 @@ function BarChart({
37
31
  emptyMessage = "No data available",
38
32
  categoryLabels
39
33
  }) {
40
- const getBarColor = (idx) => {
41
- return resolveChartColor(colors?.[idx], idx);
42
- };
43
34
  const hasWrapper = !!title;
44
35
  const wrapperClass = hasWrapper ? `rounded-lg border bg-card p-4 ${className}` : className;
45
36
  if (error) {
@@ -60,70 +51,22 @@ function BarChart({
60
51
  /* @__PURE__ */ jsx("div", { className: "flex h-40 sm:h-48 items-center justify-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }) })
61
52
  ] });
62
53
  }
63
- const isHorizontal = layout === "horizontal";
64
- const chartHeight = isHorizontal ? Math.max(200, data.length * 28) : 200;
65
- const chartContent = /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: chartHeight, children: /* @__PURE__ */ jsxs(
66
- RechartsBarChart,
67
- {
68
- data,
69
- layout: isHorizontal ? "vertical" : "horizontal",
70
- margin: { top: 5, right: 30, left: 20, bottom: 5 },
71
- children: [
72
- showGridLines && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "hsl(var(--border))" }),
73
- /* @__PURE__ */ jsx(
74
- XAxis,
75
- {
76
- type: isHorizontal ? "number" : "category",
77
- dataKey: isHorizontal ? void 0 : index,
78
- tickFormatter: isHorizontal ? valueFormatter : void 0,
79
- tick: { fontSize: 11 }
80
- }
81
- ),
82
- /* @__PURE__ */ jsx(
83
- YAxis,
84
- {
85
- type: isHorizontal ? "category" : "number",
86
- dataKey: isHorizontal ? index : void 0,
87
- tickFormatter: isHorizontal ? void 0 : valueFormatter,
88
- width: isHorizontal ? 90 : 50,
89
- interval: 0,
90
- tick: { fontSize: 10 }
91
- }
92
- ),
93
- /* @__PURE__ */ jsx(
94
- Tooltip,
95
- {
96
- content: /* @__PURE__ */ jsx(
97
- ChartTooltipContent,
98
- {
99
- valueFormatter,
100
- categoryLabels,
101
- labelFormatter: (label, payload) => {
102
- const entry = payload?.[0];
103
- const item = entry?.payload;
104
- return item?.[index] ? String(item[index]) : label;
105
- }
106
- }
107
- ),
108
- cursor: { fill: "hsl(var(--muted))", opacity: 0.2 }
109
- }
110
- ),
111
- showLegend && categories.length > 1 && /* @__PURE__ */ jsx(Legend, { verticalAlign: "top", height: 36 }),
112
- categories.map((category, idx) => /* @__PURE__ */ jsx(
113
- Bar,
114
- {
115
- dataKey: category,
116
- fill: getBarColor(idx),
117
- radius: isHorizontal ? [0, 4, 4, 0] : [4, 4, 0, 0]
118
- },
119
- category
120
- ))
121
- ]
122
- }
123
- ) });
124
54
  return /* @__PURE__ */ jsxs("div", { className: wrapperClass, children: [
125
55
  title && /* @__PURE__ */ jsx("h3", { className: "mb-4 text-base font-medium text-card-foreground", children: title }),
126
- chartContent
56
+ /* @__PURE__ */ jsx(
57
+ BarChartImpl,
58
+ {
59
+ data,
60
+ index,
61
+ categories,
62
+ colors,
63
+ layout,
64
+ valueFormatter,
65
+ showLegend,
66
+ showGridLines,
67
+ categoryLabels
68
+ }
69
+ )
127
70
  ] });
128
71
  }
129
72
  var BarChart_default = BarChart;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/charts/BarChart.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n} from 'recharts'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { ChartTooltipContent, resolveChartColor } from './ChartUtils'\n\nexport type BarChartDataItem = Record<string, string | number | null | undefined>\n\nexport type BarChartProps = {\n title?: string\n data: BarChartDataItem[]\n index: string\n categories: string[]\n loading?: boolean\n error?: string | null\n colors?: string[]\n layout?: 'vertical' | 'horizontal'\n valueFormatter?: (value: number) => string\n showLegend?: boolean\n showGridLines?: boolean\n className?: string\n emptyMessage?: string\n categoryLabels?: Record<string, string>\n}\n\nfunction defaultValueFormatter(value: number): string {\n if (Math.abs(value) >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(1)}M`\n }\n if (Math.abs(value) >= 1_000) {\n return `${(value / 1_000).toFixed(1)}K`\n }\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 })\n}\n\nexport function BarChart({\n title,\n data,\n index,\n categories,\n loading,\n error,\n colors,\n layout = 'vertical',\n valueFormatter = defaultValueFormatter,\n showLegend = true,\n showGridLines = true,\n className = '',\n emptyMessage = 'No data available',\n categoryLabels,\n}: BarChartProps) {\n const getBarColor = (idx: number): string => {\n return resolveChartColor(colors?.[idx], idx)\n }\n\n const hasWrapper = !!title\n const wrapperClass = hasWrapper ? `rounded-lg border bg-card p-4 ${className}` : className\n\n if (error) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n </div>\n )\n }\n\n if (loading) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n </div>\n )\n }\n\n if (!data || data.length === 0) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <p className=\"text-sm text-muted-foreground\">{emptyMessage}</p>\n </div>\n </div>\n )\n }\n\n const isHorizontal = layout === 'horizontal'\n const chartHeight = isHorizontal ? Math.max(200, data.length * 28) : 200\n\n const chartContent = (\n <ResponsiveContainer width=\"100%\" height={chartHeight}>\n <RechartsBarChart\n data={data}\n layout={isHorizontal ? 'vertical' : 'horizontal'}\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\n >\n {showGridLines && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"hsl(var(--border))\" />\n )}\n <XAxis\n type={isHorizontal ? 'number' : 'category'}\n dataKey={isHorizontal ? undefined : index}\n tickFormatter={isHorizontal ? valueFormatter : undefined}\n tick={{ fontSize: 11 }}\n />\n <YAxis\n type={isHorizontal ? 'category' : 'number'}\n dataKey={isHorizontal ? index : undefined}\n tickFormatter={isHorizontal ? undefined : valueFormatter}\n width={isHorizontal ? 90 : 50}\n interval={0}\n tick={{ fontSize: 10 }}\n />\n <Tooltip\n content={\n <ChartTooltipContent\n valueFormatter={valueFormatter}\n categoryLabels={categoryLabels}\n labelFormatter={(label, payload) => {\n const entry = payload?.[0] as { payload?: BarChartDataItem } | undefined\n const item = entry?.payload\n return item?.[index] ? String(item[index]) : label\n }}\n />\n }\n cursor={{ fill: 'hsl(var(--muted))', opacity: 0.2 }}\n />\n {showLegend && categories.length > 1 && (\n <Legend verticalAlign=\"top\" height={36} />\n )}\n {categories.map((category, idx) => (\n <Bar\n key={category}\n dataKey={category}\n fill={getBarColor(idx)}\n radius={isHorizontal ? [0, 4, 4, 0] : [4, 4, 0, 0]}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n )\n\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n {chartContent}\n </div>\n )\n}\n\nexport default BarChart\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport dynamic from 'next/dynamic'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\n\nexport type BarChartDataItem = Record<string, string | number | null | undefined>\n\nexport type BarChartProps = {\n title?: string\n data: BarChartDataItem[]\n index: string\n categories: string[]\n loading?: boolean\n error?: string | null\n colors?: string[]\n layout?: 'vertical' | 'horizontal'\n valueFormatter?: (value: number) => string\n showLegend?: boolean\n showGridLines?: boolean\n className?: string\n emptyMessage?: string\n categoryLabels?: Record<string, string>\n}\n\nfunction defaultValueFormatter(value: number): string {\n if (Math.abs(value) >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(1)}M`\n }\n if (Math.abs(value) >= 1_000) {\n return `${(value / 1_000).toFixed(1)}K`\n }\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 })\n}\n\nconst BarChartImpl = dynamic(() => import('./BarChartImpl'), {\n ssr: false,\n loading: () => (\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n ),\n})\n\nexport function BarChart({\n title,\n data,\n index,\n categories,\n loading,\n error,\n colors,\n layout = 'vertical',\n valueFormatter = defaultValueFormatter,\n showLegend = true,\n showGridLines = true,\n className = '',\n emptyMessage = 'No data available',\n categoryLabels,\n}: BarChartProps) {\n const hasWrapper = !!title\n const wrapperClass = hasWrapper ? `rounded-lg border bg-card p-4 ${className}` : className\n\n if (error) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n </div>\n )\n }\n\n if (loading) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n </div>\n )\n }\n\n if (!data || data.length === 0) {\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-40 sm:h-48 items-center justify-center\">\n <p className=\"text-sm text-muted-foreground\">{emptyMessage}</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={wrapperClass}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <BarChartImpl\n data={data}\n index={index}\n categories={categories}\n colors={colors}\n layout={layout}\n valueFormatter={valueFormatter}\n showLegend={showLegend}\n showGridLines={showGridLines}\n categoryLabels={categoryLabels}\n />\n </div>\n )\n}\n\nexport default BarChart\n"],
5
+ "mappings": ";AAuCM,cA0BA,YA1BA;AApCN,OAAO,aAAa;AACpB,SAAS,eAAe;AAqBxB,SAAS,sBAAsB,OAAuB;AACpD,MAAI,KAAK,IAAI,KAAK,KAAK,KAAW;AAChC,WAAO,IAAI,QAAQ,KAAW,QAAQ,CAAC,CAAC;AAAA,EAC1C;AACA,MAAI,KAAK,IAAI,KAAK,KAAK,KAAO;AAC5B,WAAO,IAAI,QAAQ,KAAO,QAAQ,CAAC,CAAC;AAAA,EACtC;AACA,SAAO,MAAM,eAAe,QAAW,EAAE,uBAAuB,EAAE,CAAC;AACrE;AAEA,MAAM,eAAe,QAAQ,MAAM,OAAO,gBAAgB,GAAG;AAAA,EAC3D,KAAK;AAAA,EACL,SAAS,MACP,oBAAC,SAAI,WAAU,iDACb,8BAAC,WAAQ,WAAU,iCAAgC,GACrD;AAEJ,CAAC;AAEM,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf;AACF,GAAkB;AAChB,QAAM,aAAa,CAAC,CAAC;AACrB,QAAM,eAAe,aAAa,iCAAiC,SAAS,KAAK;AAEjF,MAAI,OAAO;AACT,WACE,qBAAC,SAAI,WAAW,cACb;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,iDACb,8BAAC,OAAE,WAAU,4BAA4B,iBAAM,GACjD;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAW,cACb;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,iDACb,8BAAC,WAAQ,WAAU,iCAAgC,GACrD;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC9B,WACE,qBAAC,SAAI,WAAW,cACb;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,iDACb,8BAAC,OAAE,WAAU,iCAAiC,wBAAa,GAC7D;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAW,cACb;AAAA,aAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,IACjF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAEA,IAAO,mBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ BarChart as RechartsBarChart,
5
+ Bar,
6
+ XAxis,
7
+ YAxis,
8
+ CartesianGrid,
9
+ Tooltip,
10
+ Legend,
11
+ ResponsiveContainer
12
+ } from "recharts";
13
+ import { ChartTooltipContent, resolveChartColor } from "./ChartUtils.js";
14
+ function BarChartImpl({
15
+ data,
16
+ index,
17
+ categories,
18
+ colors,
19
+ layout = "vertical",
20
+ valueFormatter,
21
+ showLegend = true,
22
+ showGridLines = true,
23
+ categoryLabels
24
+ }) {
25
+ const isHorizontal = layout === "horizontal";
26
+ const chartHeight = isHorizontal ? Math.max(200, data.length * 28) : 200;
27
+ const getBarColor = (idx) => resolveChartColor(colors?.[idx], idx);
28
+ return /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: chartHeight, children: /* @__PURE__ */ jsxs(
29
+ RechartsBarChart,
30
+ {
31
+ data,
32
+ layout: isHorizontal ? "vertical" : "horizontal",
33
+ margin: { top: 5, right: 30, left: 20, bottom: 5 },
34
+ children: [
35
+ showGridLines && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "hsl(var(--border))" }),
36
+ /* @__PURE__ */ jsx(
37
+ XAxis,
38
+ {
39
+ type: isHorizontal ? "number" : "category",
40
+ dataKey: isHorizontal ? void 0 : index,
41
+ tickFormatter: isHorizontal ? valueFormatter : void 0,
42
+ tick: { fontSize: 11 }
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx(
46
+ YAxis,
47
+ {
48
+ type: isHorizontal ? "category" : "number",
49
+ dataKey: isHorizontal ? index : void 0,
50
+ tickFormatter: isHorizontal ? void 0 : valueFormatter,
51
+ width: isHorizontal ? 90 : 50,
52
+ interval: 0,
53
+ tick: { fontSize: 10 }
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsx(
57
+ Tooltip,
58
+ {
59
+ content: /* @__PURE__ */ jsx(
60
+ ChartTooltipContent,
61
+ {
62
+ valueFormatter,
63
+ categoryLabels,
64
+ labelFormatter: (label, payload) => {
65
+ const entry = payload?.[0];
66
+ const item = entry?.payload;
67
+ return item?.[index] ? String(item[index]) : label;
68
+ }
69
+ }
70
+ ),
71
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.2 }
72
+ }
73
+ ),
74
+ showLegend && categories.length > 1 && /* @__PURE__ */ jsx(Legend, { verticalAlign: "top", height: 36 }),
75
+ categories.map((category, idx) => /* @__PURE__ */ jsx(
76
+ Bar,
77
+ {
78
+ dataKey: category,
79
+ fill: getBarColor(idx),
80
+ radius: isHorizontal ? [0, 4, 4, 0] : [4, 4, 0, 0]
81
+ },
82
+ category
83
+ ))
84
+ ]
85
+ }
86
+ ) });
87
+ }
88
+ export {
89
+ BarChartImpl as default
90
+ };
91
+ //# sourceMappingURL=BarChartImpl.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/backend/charts/BarChartImpl.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n} from 'recharts'\nimport { ChartTooltipContent, resolveChartColor } from './ChartUtils'\nimport type { BarChartDataItem, BarChartProps } from './BarChart'\n\ntype ImplProps = Pick<\n BarChartProps,\n | 'data'\n | 'index'\n | 'categories'\n | 'colors'\n | 'layout'\n | 'valueFormatter'\n | 'showLegend'\n | 'showGridLines'\n | 'categoryLabels'\n> & {\n valueFormatter: (value: number) => string\n}\n\nexport default function BarChartImpl({\n data,\n index,\n categories,\n colors,\n layout = 'vertical',\n valueFormatter,\n showLegend = true,\n showGridLines = true,\n categoryLabels,\n}: ImplProps) {\n const isHorizontal = layout === 'horizontal'\n const chartHeight = isHorizontal ? Math.max(200, data.length * 28) : 200\n const getBarColor = (idx: number): string => resolveChartColor(colors?.[idx], idx)\n\n return (\n <ResponsiveContainer width=\"100%\" height={chartHeight}>\n <RechartsBarChart\n data={data}\n layout={isHorizontal ? 'vertical' : 'horizontal'}\n margin={{ top: 5, right: 30, left: 20, bottom: 5 }}\n >\n {showGridLines && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"hsl(var(--border))\" />\n )}\n <XAxis\n type={isHorizontal ? 'number' : 'category'}\n dataKey={isHorizontal ? undefined : index}\n tickFormatter={isHorizontal ? valueFormatter : undefined}\n tick={{ fontSize: 11 }}\n />\n <YAxis\n type={isHorizontal ? 'category' : 'number'}\n dataKey={isHorizontal ? index : undefined}\n tickFormatter={isHorizontal ? undefined : valueFormatter}\n width={isHorizontal ? 90 : 50}\n interval={0}\n tick={{ fontSize: 10 }}\n />\n <Tooltip\n content={\n <ChartTooltipContent\n valueFormatter={valueFormatter}\n categoryLabels={categoryLabels}\n labelFormatter={(label, payload) => {\n const entry = payload?.[0] as { payload?: BarChartDataItem } | undefined\n const item = entry?.payload\n return item?.[index] ? String(item[index]) : label\n }}\n />\n }\n cursor={{ fill: 'hsl(var(--muted))', opacity: 0.2 }}\n />\n {showLegend && categories.length > 1 && (\n <Legend verticalAlign=\"top\" height={36} />\n )}\n {categories.map((category, idx) => (\n <Bar\n key={category}\n dataKey={category}\n fill={getBarColor(idx)}\n radius={isHorizontal ? [0, 4, 4, 0] : [4, 4, 0, 0]}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n )\n}\n"],
5
+ "mappings": ";AAgDM,SAMI,KANJ;AA7CN;AAAA,EACE,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB,yBAAyB;AAkBxC,SAAR,aAA8B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB;AACF,GAAc;AACZ,QAAM,eAAe,WAAW;AAChC,QAAM,cAAc,eAAe,KAAK,IAAI,KAAK,KAAK,SAAS,EAAE,IAAI;AACrE,QAAM,cAAc,CAAC,QAAwB,kBAAkB,SAAS,GAAG,GAAG,GAAG;AAEjF,SACE,oBAAC,uBAAoB,OAAM,QAAO,QAAQ,aACxC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,QAAQ,eAAe,aAAa;AAAA,MACpC,QAAQ,EAAE,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,QAAQ,EAAE;AAAA,MAEhD;AAAA,yBACC,oBAAC,iBAAc,iBAAgB,OAAM,QAAO,sBAAqB;AAAA,QAEnE;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,eAAe,WAAW;AAAA,YAChC,SAAS,eAAe,SAAY;AAAA,YACpC,eAAe,eAAe,iBAAiB;AAAA,YAC/C,MAAM,EAAE,UAAU,GAAG;AAAA;AAAA,QACvB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,eAAe,aAAa;AAAA,YAClC,SAAS,eAAe,QAAQ;AAAA,YAChC,eAAe,eAAe,SAAY;AAAA,YAC1C,OAAO,eAAe,KAAK;AAAA,YAC3B,UAAU;AAAA,YACV,MAAM,EAAE,UAAU,GAAG;AAAA;AAAA,QACvB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SACE;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,gBAAgB,CAAC,OAAO,YAAY;AAClC,wBAAM,QAAQ,UAAU,CAAC;AACzB,wBAAM,OAAO,OAAO;AACpB,yBAAO,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC,IAAI;AAAA,gBAC/C;AAAA;AAAA,YACF;AAAA,YAEF,QAAQ,EAAE,MAAM,qBAAqB,SAAS,IAAI;AAAA;AAAA,QACpD;AAAA,QACC,cAAc,WAAW,SAAS,KACjC,oBAAC,UAAO,eAAc,OAAM,QAAQ,IAAI;AAAA,QAEzC,WAAW,IAAI,CAAC,UAAU,QACzB;AAAA,UAAC;AAAA;AAAA,YAEC,SAAS;AAAA,YACT,MAAM,YAAY,GAAG;AAAA,YACrB,QAAQ,eAAe,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA;AAAA,UAH5C;AAAA,QAIP,CACD;AAAA;AAAA;AAAA,EACH,GACF;AAEJ;",
6
+ "names": []
7
+ }
@@ -1,19 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import {
4
- LineChart as RechartsLineChart,
5
- AreaChart as RechartsAreaChart,
6
- Line,
7
- Area,
8
- XAxis,
9
- YAxis,
10
- CartesianGrid,
11
- Tooltip,
12
- ResponsiveContainer,
13
- Legend
14
- } from "recharts";
3
+ import dynamic from "next/dynamic";
15
4
  import { Spinner } from "@open-mercato/ui/primitives/spinner";
16
- import { ChartTooltipContent, resolveChartColor } from "./ChartUtils.js";
17
5
  function defaultValueFormatter(value) {
18
6
  if (Math.abs(value) >= 1e6) {
19
7
  return `${(value / 1e6).toFixed(1)}M`;
@@ -23,6 +11,10 @@ function defaultValueFormatter(value) {
23
11
  }
24
12
  return value.toLocaleString(void 0, { maximumFractionDigits: 2 });
25
13
  }
14
+ const LineChartImpl = dynamic(() => import("./LineChartImpl.js"), {
15
+ ssr: false,
16
+ loading: () => /* @__PURE__ */ jsx("div", { className: "flex h-48 items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { className: "h-6 w-6 text-muted-foreground" }) })
17
+ });
26
18
  function LineChart({
27
19
  title,
28
20
  data,
@@ -41,9 +33,6 @@ function LineChart({
41
33
  emptyMessage = "No data available",
42
34
  categoryLabels
43
35
  }) {
44
- const getLineColor = (idx) => {
45
- return resolveChartColor(colors?.[idx], idx);
46
- };
47
36
  if (error) {
48
37
  return /* @__PURE__ */ jsxs("div", { className: `rounded-lg border bg-card p-4 ${className}`, children: [
49
38
  title && /* @__PURE__ */ jsx("h3", { className: "mb-4 text-base font-medium text-card-foreground", children: title }),
@@ -62,86 +51,24 @@ function LineChart({
62
51
  /* @__PURE__ */ jsx("div", { className: "flex h-48 items-center justify-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }) })
63
52
  ] });
64
53
  }
65
- const ChartComponent = showArea ? RechartsAreaChart : RechartsLineChart;
66
54
  return /* @__PURE__ */ jsxs("div", { className: `rounded-lg border bg-card p-4 ${className}`, children: [
67
55
  title && /* @__PURE__ */ jsx("h3", { className: "mb-4 text-base font-medium text-card-foreground", children: title }),
68
- /* @__PURE__ */ jsx("div", { className: "h-52 w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
69
- ChartComponent,
56
+ /* @__PURE__ */ jsx("div", { className: "h-52 w-full", children: /* @__PURE__ */ jsx(
57
+ LineChartImpl,
70
58
  {
71
59
  data,
72
- margin: { top: 5, right: 10, left: 10, bottom: 5 },
73
- children: [
74
- showGridLines && /* @__PURE__ */ jsx(
75
- CartesianGrid,
76
- {
77
- strokeDasharray: "3 3",
78
- stroke: "hsl(var(--border))"
79
- }
80
- ),
81
- /* @__PURE__ */ jsx(
82
- XAxis,
83
- {
84
- dataKey: index,
85
- tick: { fontSize: 12 },
86
- tickLine: false,
87
- axisLine: false
88
- }
89
- ),
90
- /* @__PURE__ */ jsx(
91
- YAxis,
92
- {
93
- tickFormatter: valueFormatter,
94
- tick: { fontSize: 12 },
95
- tickLine: false,
96
- axisLine: false,
97
- width: 56
98
- }
99
- ),
100
- /* @__PURE__ */ jsx(
101
- Tooltip,
102
- {
103
- content: /* @__PURE__ */ jsx(ChartTooltipContent, { valueFormatter, categoryLabels }),
104
- cursor: { stroke: "hsl(var(--muted-foreground))", strokeDasharray: "3 3" }
105
- }
106
- ),
107
- showLegend && categories.length > 1 && /* @__PURE__ */ jsx(
108
- Legend,
109
- {
110
- verticalAlign: "top",
111
- height: 36,
112
- formatter: (value) => /* @__PURE__ */ jsx("span", { style: { color: "hsl(var(--muted-foreground))", fontSize: "12px" }, children: value })
113
- }
114
- ),
115
- showArea ? categories.map((category, idx) => /* @__PURE__ */ jsx(
116
- Area,
117
- {
118
- type: curveType,
119
- dataKey: category,
120
- stroke: getLineColor(idx),
121
- fill: getLineColor(idx),
122
- fillOpacity: 0.2,
123
- strokeWidth: 2,
124
- connectNulls,
125
- dot: false,
126
- activeDot: { r: 4, strokeWidth: 0 }
127
- },
128
- category
129
- )) : categories.map((category, idx) => /* @__PURE__ */ jsx(
130
- Line,
131
- {
132
- type: curveType,
133
- dataKey: category,
134
- stroke: getLineColor(idx),
135
- strokeWidth: 2,
136
- connectNulls,
137
- dot: false,
138
- activeDot: { r: 4, strokeWidth: 0 }
139
- },
140
- category
141
- ))
142
- ]
60
+ index,
61
+ categories,
62
+ colors,
63
+ showArea,
64
+ valueFormatter,
65
+ showLegend,
66
+ showGridLines,
67
+ curveType,
68
+ connectNulls,
69
+ categoryLabels
143
70
  }
144
- ) }) })
71
+ ) })
145
72
  ] });
146
73
  }
147
74
  var LineChart_default = LineChart;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/charts/LineChart.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n LineChart as RechartsLineChart,\n AreaChart as RechartsAreaChart,\n Line,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n} from 'recharts'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { ChartTooltipContent, resolveChartColor } from './ChartUtils'\n\nexport type LineChartDataItem = Record<string, string | number | null | undefined>\n\nexport type LineChartProps = {\n title?: string\n data: LineChartDataItem[]\n index: string\n categories: string[]\n loading?: boolean\n error?: string | null\n colors?: string[]\n showArea?: boolean\n valueFormatter?: (value: number) => string\n showLegend?: boolean\n showGridLines?: boolean\n curveType?: 'linear' | 'natural' | 'monotone' | 'step'\n connectNulls?: boolean\n className?: string\n emptyMessage?: string\n categoryLabels?: Record<string, string>\n}\n\nfunction defaultValueFormatter(value: number): string {\n if (Math.abs(value) >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(1)}M`\n }\n if (Math.abs(value) >= 1_000) {\n return `${(value / 1_000).toFixed(1)}K`\n }\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 })\n}\n\nexport function LineChart({\n title,\n data,\n index,\n categories,\n loading,\n error,\n colors,\n showArea = false,\n valueFormatter = defaultValueFormatter,\n showLegend = true,\n showGridLines = true,\n curveType = 'monotone',\n connectNulls = true,\n className = '',\n emptyMessage = 'No data available',\n categoryLabels,\n}: LineChartProps) {\n const getLineColor = (idx: number): string => {\n return resolveChartColor(colors?.[idx], idx)\n }\n\n if (error) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n </div>\n )\n }\n\n if (loading) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n </div>\n )\n }\n\n if (!data || data.length === 0) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <p className=\"text-sm text-muted-foreground\">{emptyMessage}</p>\n </div>\n </div>\n )\n }\n\n const ChartComponent = showArea ? RechartsAreaChart : RechartsLineChart\n\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"h-52 w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ChartComponent\n data={data}\n margin={{ top: 5, right: 10, left: 10, bottom: 5 }}\n >\n {showGridLines && (\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"hsl(var(--border))\"\n />\n )}\n <XAxis\n dataKey={index}\n tick={{ fontSize: 12 }}\n tickLine={false}\n axisLine={false}\n />\n <YAxis\n tickFormatter={valueFormatter}\n tick={{ fontSize: 12 }}\n tickLine={false}\n axisLine={false}\n width={56}\n />\n <Tooltip\n content={<ChartTooltipContent valueFormatter={valueFormatter} categoryLabels={categoryLabels} />}\n cursor={{ stroke: 'hsl(var(--muted-foreground))', strokeDasharray: '3 3' }}\n />\n {showLegend && categories.length > 1 && (\n <Legend\n verticalAlign=\"top\"\n height={36}\n formatter={(value) => (\n <span style={{ color: 'hsl(var(--muted-foreground))', fontSize: '12px' }}>{value}</span>\n )}\n />\n )}\n {showArea\n ? categories.map((category, idx) => (\n <Area\n key={category}\n type={curveType}\n dataKey={category}\n stroke={getLineColor(idx)}\n fill={getLineColor(idx)}\n fillOpacity={0.2}\n strokeWidth={2}\n connectNulls={connectNulls}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 0 }}\n />\n ))\n : categories.map((category, idx) => (\n <Line\n key={category}\n type={curveType}\n dataKey={category}\n stroke={getLineColor(idx)}\n strokeWidth={2}\n connectNulls={connectNulls}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 0 }}\n />\n ))}\n </ChartComponent>\n </ResponsiveContainer>\n </div>\n </div>\n )\n}\n\nexport default LineChart\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport dynamic from 'next/dynamic'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\n\nexport type LineChartDataItem = Record<string, string | number | null | undefined>\n\nexport type LineChartProps = {\n title?: string\n data: LineChartDataItem[]\n index: string\n categories: string[]\n loading?: boolean\n error?: string | null\n colors?: string[]\n showArea?: boolean\n valueFormatter?: (value: number) => string\n showLegend?: boolean\n showGridLines?: boolean\n curveType?: 'linear' | 'natural' | 'monotone' | 'step'\n connectNulls?: boolean\n className?: string\n emptyMessage?: string\n categoryLabels?: Record<string, string>\n}\n\nfunction defaultValueFormatter(value: number): string {\n if (Math.abs(value) >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(1)}M`\n }\n if (Math.abs(value) >= 1_000) {\n return `${(value / 1_000).toFixed(1)}K`\n }\n return value.toLocaleString(undefined, { maximumFractionDigits: 2 })\n}\n\nconst LineChartImpl = dynamic(() => import('./LineChartImpl'), {\n ssr: false,\n loading: () => (\n <div className=\"flex h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n ),\n})\n\nexport function LineChart({\n title,\n data,\n index,\n categories,\n loading,\n error,\n colors,\n showArea = false,\n valueFormatter = defaultValueFormatter,\n showLegend = true,\n showGridLines = true,\n curveType = 'monotone',\n connectNulls = true,\n className = '',\n emptyMessage = 'No data available',\n categoryLabels,\n}: LineChartProps) {\n if (error) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n </div>\n )\n }\n\n if (loading) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n </div>\n )\n }\n\n if (!data || data.length === 0) {\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"flex h-48 items-center justify-center\">\n <p className=\"text-sm text-muted-foreground\">{emptyMessage}</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`rounded-lg border bg-card p-4 ${className}`}>\n {title && <h3 className=\"mb-4 text-base font-medium text-card-foreground\">{title}</h3>}\n <div className=\"h-52 w-full\">\n <LineChartImpl\n data={data}\n index={index}\n categories={categories}\n colors={colors}\n showArea={showArea}\n valueFormatter={valueFormatter}\n showLegend={showLegend}\n showGridLines={showGridLines}\n curveType={curveType}\n connectNulls={connectNulls}\n categoryLabels={categoryLabels}\n />\n </div>\n </div>\n )\n}\n\nexport default LineChart\n"],
5
+ "mappings": ";AAyCM,cAyBA,YAzBA;AAtCN,OAAO,aAAa;AACpB,SAAS,eAAe;AAuBxB,SAAS,sBAAsB,OAAuB;AACpD,MAAI,KAAK,IAAI,KAAK,KAAK,KAAW;AAChC,WAAO,IAAI,QAAQ,KAAW,QAAQ,CAAC,CAAC;AAAA,EAC1C;AACA,MAAI,KAAK,IAAI,KAAK,KAAK,KAAO;AAC5B,WAAO,IAAI,QAAQ,KAAO,QAAQ,CAAC,CAAC;AAAA,EACtC;AACA,SAAO,MAAM,eAAe,QAAW,EAAE,uBAAuB,EAAE,CAAC;AACrE;AAEA,MAAM,gBAAgB,QAAQ,MAAM,OAAO,iBAAiB,GAAG;AAAA,EAC7D,KAAK;AAAA,EACL,SAAS,MACP,oBAAC,SAAI,WAAU,yCACb,8BAAC,WAAQ,WAAU,iCAAgC,GACrD;AAEJ,CAAC;AAEM,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,eAAe;AAAA,EACf;AACF,GAAmB;AACjB,MAAI,OAAO;AACT,WACE,qBAAC,SAAI,WAAW,iCAAiC,SAAS,IACvD;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,yCACb,8BAAC,OAAE,WAAU,4BAA4B,iBAAM,GACjD;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAW,iCAAiC,SAAS,IACvD;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,yCACb,8BAAC,WAAQ,WAAU,iCAAgC,GACrD;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC9B,WACE,qBAAC,SAAI,WAAW,iCAAiC,SAAS,IACvD;AAAA,eAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,MACjF,oBAAC,SAAI,WAAU,yCACb,8BAAC,OAAE,WAAU,iCAAiC,wBAAa,GAC7D;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAW,iCAAiC,SAAS,IACvD;AAAA,aAAS,oBAAC,QAAG,WAAU,mDAAmD,iBAAM;AAAA,IACjF,oBAAC,SAAI,WAAU,eACb;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;AAEA,IAAO,oBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,112 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ LineChart as RechartsLineChart,
5
+ AreaChart as RechartsAreaChart,
6
+ Line,
7
+ Area,
8
+ XAxis,
9
+ YAxis,
10
+ CartesianGrid,
11
+ Tooltip,
12
+ ResponsiveContainer,
13
+ Legend
14
+ } from "recharts";
15
+ import { ChartTooltipContent, resolveChartColor } from "./ChartUtils.js";
16
+ function LineChartImpl({
17
+ data,
18
+ index,
19
+ categories,
20
+ colors,
21
+ showArea = false,
22
+ valueFormatter,
23
+ showLegend = true,
24
+ showGridLines = true,
25
+ curveType = "monotone",
26
+ connectNulls = true,
27
+ categoryLabels
28
+ }) {
29
+ const getLineColor = (idx) => resolveChartColor(colors?.[idx], idx);
30
+ const ChartComponent = showArea ? RechartsAreaChart : RechartsLineChart;
31
+ return /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
32
+ ChartComponent,
33
+ {
34
+ data,
35
+ margin: { top: 5, right: 10, left: 10, bottom: 5 },
36
+ children: [
37
+ showGridLines && /* @__PURE__ */ jsx(
38
+ CartesianGrid,
39
+ {
40
+ strokeDasharray: "3 3",
41
+ stroke: "hsl(var(--border))"
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsx(
45
+ XAxis,
46
+ {
47
+ dataKey: index,
48
+ tick: { fontSize: 12 },
49
+ tickLine: false,
50
+ axisLine: false
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx(
54
+ YAxis,
55
+ {
56
+ tickFormatter: valueFormatter,
57
+ tick: { fontSize: 12 },
58
+ tickLine: false,
59
+ axisLine: false,
60
+ width: 56
61
+ }
62
+ ),
63
+ /* @__PURE__ */ jsx(
64
+ Tooltip,
65
+ {
66
+ content: /* @__PURE__ */ jsx(ChartTooltipContent, { valueFormatter, categoryLabels }),
67
+ cursor: { stroke: "hsl(var(--muted-foreground))", strokeDasharray: "3 3" }
68
+ }
69
+ ),
70
+ showLegend && categories.length > 1 && /* @__PURE__ */ jsx(
71
+ Legend,
72
+ {
73
+ verticalAlign: "top",
74
+ height: 36,
75
+ formatter: (value) => /* @__PURE__ */ jsx("span", { style: { color: "hsl(var(--muted-foreground))", fontSize: "12px" }, children: value })
76
+ }
77
+ ),
78
+ showArea ? categories.map((category, idx) => /* @__PURE__ */ jsx(
79
+ Area,
80
+ {
81
+ type: curveType,
82
+ dataKey: category,
83
+ stroke: getLineColor(idx),
84
+ fill: getLineColor(idx),
85
+ fillOpacity: 0.2,
86
+ strokeWidth: 2,
87
+ connectNulls,
88
+ dot: false,
89
+ activeDot: { r: 4, strokeWidth: 0 }
90
+ },
91
+ category
92
+ )) : categories.map((category, idx) => /* @__PURE__ */ jsx(
93
+ Line,
94
+ {
95
+ type: curveType,
96
+ dataKey: category,
97
+ stroke: getLineColor(idx),
98
+ strokeWidth: 2,
99
+ connectNulls,
100
+ dot: false,
101
+ activeDot: { r: 4, strokeWidth: 0 }
102
+ },
103
+ category
104
+ ))
105
+ ]
106
+ }
107
+ ) });
108
+ }
109
+ export {
110
+ LineChartImpl as default
111
+ };
112
+ //# sourceMappingURL=LineChartImpl.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/backend/charts/LineChartImpl.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n LineChart as RechartsLineChart,\n AreaChart as RechartsAreaChart,\n Line,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n} from 'recharts'\nimport { ChartTooltipContent, resolveChartColor } from './ChartUtils'\nimport type { LineChartProps } from './LineChart'\n\ntype ImplProps = Pick<\n LineChartProps,\n | 'data'\n | 'index'\n | 'categories'\n | 'colors'\n | 'showArea'\n | 'valueFormatter'\n | 'showLegend'\n | 'showGridLines'\n | 'curveType'\n | 'connectNulls'\n | 'categoryLabels'\n> & {\n valueFormatter: (value: number) => string\n}\n\nexport default function LineChartImpl({\n data,\n index,\n categories,\n colors,\n showArea = false,\n valueFormatter,\n showLegend = true,\n showGridLines = true,\n curveType = 'monotone',\n connectNulls = true,\n categoryLabels,\n}: ImplProps) {\n const getLineColor = (idx: number): string => resolveChartColor(colors?.[idx], idx)\n const ChartComponent = showArea ? RechartsAreaChart : RechartsLineChart\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ChartComponent\n data={data}\n margin={{ top: 5, right: 10, left: 10, bottom: 5 }}\n >\n {showGridLines && (\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"hsl(var(--border))\"\n />\n )}\n <XAxis\n dataKey={index}\n tick={{ fontSize: 12 }}\n tickLine={false}\n axisLine={false}\n />\n <YAxis\n tickFormatter={valueFormatter}\n tick={{ fontSize: 12 }}\n tickLine={false}\n axisLine={false}\n width={56}\n />\n <Tooltip\n content={<ChartTooltipContent valueFormatter={valueFormatter} categoryLabels={categoryLabels} />}\n cursor={{ stroke: 'hsl(var(--muted-foreground))', strokeDasharray: '3 3' }}\n />\n {showLegend && categories.length > 1 && (\n <Legend\n verticalAlign=\"top\"\n height={36}\n formatter={(value) => (\n <span style={{ color: 'hsl(var(--muted-foreground))', fontSize: '12px' }}>{value}</span>\n )}\n />\n )}\n {showArea\n ? categories.map((category, idx) => (\n <Area\n key={category}\n type={curveType}\n dataKey={category}\n stroke={getLineColor(idx)}\n fill={getLineColor(idx)}\n fillOpacity={0.2}\n strokeWidth={2}\n connectNulls={connectNulls}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 0 }}\n />\n ))\n : categories.map((category, idx) => (\n <Line\n key={category}\n type={curveType}\n dataKey={category}\n stroke={getLineColor(idx)}\n strokeWidth={2}\n connectNulls={connectNulls}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 0 }}\n />\n ))}\n </ChartComponent>\n </ResponsiveContainer>\n )\n}\n"],
5
+ "mappings": ";AAqDM,SAKI,KALJ;AAlDN;AAAA,EACE,aAAa;AAAA,EACb,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB,yBAAyB;AAoBxC,SAAR,cAA+B;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf;AACF,GAAc;AACZ,QAAM,eAAe,CAAC,QAAwB,kBAAkB,SAAS,GAAG,GAAG,GAAG;AAClF,QAAM,iBAAiB,WAAW,oBAAoB;AAEtD,SACE,oBAAC,uBAAoB,OAAM,QAAO,QAAO,QACvC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,QAAQ,EAAE,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,QAAQ,EAAE;AAAA,MAEhD;AAAA,yBACC;AAAA,UAAC;AAAA;AAAA,YACC,iBAAgB;AAAA,YAChB,QAAO;AAAA;AAAA,QACT;AAAA,QAEF;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,MAAM,EAAE,UAAU,GAAG;AAAA,YACrB,UAAU;AAAA,YACV,UAAU;AAAA;AAAA,QACZ;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,eAAe;AAAA,YACf,MAAM,EAAE,UAAU,GAAG;AAAA,YACrB,UAAU;AAAA,YACV,UAAU;AAAA,YACV,OAAO;AAAA;AAAA,QACT;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,oBAAC,uBAAoB,gBAAgC,gBAAgC;AAAA,YAC9F,QAAQ,EAAE,QAAQ,gCAAgC,iBAAiB,MAAM;AAAA;AAAA,QAC3E;AAAA,QACC,cAAc,WAAW,SAAS,KACjC;AAAA,UAAC;AAAA;AAAA,YACC,eAAc;AAAA,YACd,QAAQ;AAAA,YACR,WAAW,CAAC,UACV,oBAAC,UAAK,OAAO,EAAE,OAAO,gCAAgC,UAAU,OAAO,GAAI,iBAAM;AAAA;AAAA,QAErF;AAAA,QAED,WACG,WAAW,IAAI,CAAC,UAAU,QACxB;AAAA,UAAC;AAAA;AAAA,YAEC,MAAM;AAAA,YACN,SAAS;AAAA,YACT,QAAQ,aAAa,GAAG;AAAA,YACxB,MAAM,aAAa,GAAG;AAAA,YACtB,aAAa;AAAA,YACb,aAAa;AAAA,YACb;AAAA,YACA,KAAK;AAAA,YACL,WAAW,EAAE,GAAG,GAAG,aAAa,EAAE;AAAA;AAAA,UAT7B;AAAA,QAUP,CACD,IACD,WAAW,IAAI,CAAC,UAAU,QACxB;AAAA,UAAC;AAAA;AAAA,YAEC,MAAM;AAAA,YACN,SAAS;AAAA,YACT,QAAQ,aAAa,GAAG;AAAA,YACxB,aAAa;AAAA,YACb;AAAA,YACA,KAAK;AAAA,YACL,WAAW,EAAE,GAAG,GAAG,aAAa,EAAE;AAAA;AAAA,UAP7B;AAAA,QAQP,CACD;AAAA;AAAA;AAAA,EACP,GACF;AAEJ;",
6
+ "names": []
7
+ }