@alpic-ai/ui 0.0.0-dev.g00dcac1 → 0.0.0-dev.g014cfc8

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 (60) hide show
  1. package/dist/components/area-chart.d.mts +64 -0
  2. package/dist/components/area-chart.mjs +275 -0
  3. package/dist/components/bar-chart.d.mts +50 -0
  4. package/dist/components/bar-chart.mjs +262 -0
  5. package/dist/components/bar-list.d.mts +31 -0
  6. package/dist/components/bar-list.mjs +111 -0
  7. package/dist/components/chart-card.d.mts +25 -0
  8. package/dist/components/chart-card.mjs +48 -0
  9. package/dist/components/chart-container.d.mts +20 -0
  10. package/dist/components/chart-container.mjs +37 -0
  11. package/dist/components/chart-legend.d.mts +21 -0
  12. package/dist/components/chart-legend.mjs +35 -0
  13. package/dist/components/chart-tooltip.d.mts +33 -0
  14. package/dist/components/chart-tooltip.mjs +52 -0
  15. package/dist/components/donut-chart.d.mts +46 -0
  16. package/dist/components/donut-chart.mjs +189 -0
  17. package/dist/components/form.mjs +1 -1
  18. package/dist/components/heatmap-chart.d.mts +48 -0
  19. package/dist/components/heatmap-chart.mjs +229 -0
  20. package/dist/components/line-chart.d.mts +57 -0
  21. package/dist/components/line-chart.mjs +218 -0
  22. package/dist/components/stat.d.mts +32 -0
  23. package/dist/components/stat.mjs +117 -0
  24. package/dist/components/wizard.d.mts +1 -19
  25. package/dist/components/wizard.mjs +1 -19
  26. package/dist/hooks/use-chart-theme.d.mts +18 -0
  27. package/dist/hooks/use-chart-theme.mjs +57 -0
  28. package/dist/hooks/use-reduced-motion.d.mts +4 -0
  29. package/dist/hooks/use-reduced-motion.mjs +16 -0
  30. package/dist/lib/chart-palette.d.mts +4 -0
  31. package/dist/lib/chart-palette.mjs +95 -0
  32. package/dist/lib/chart.d.mts +14 -0
  33. package/dist/lib/chart.mjs +42 -0
  34. package/package.json +24 -23
  35. package/src/components/area-chart.tsx +347 -0
  36. package/src/components/bar-chart.tsx +317 -0
  37. package/src/components/bar-list.tsx +166 -0
  38. package/src/components/chart-card.tsx +65 -0
  39. package/src/components/chart-container.tsx +51 -0
  40. package/src/components/chart-legend.tsx +49 -0
  41. package/src/components/chart-tooltip.tsx +93 -0
  42. package/src/components/donut-chart.tsx +217 -0
  43. package/src/components/form.tsx +1 -1
  44. package/src/components/heatmap-chart.tsx +331 -0
  45. package/src/components/line-chart.tsx +277 -0
  46. package/src/components/stat.tsx +113 -0
  47. package/src/components/wizard.tsx +1 -35
  48. package/src/hooks/use-chart-theme.ts +75 -0
  49. package/src/hooks/use-reduced-motion.ts +17 -0
  50. package/src/lib/chart-palette.ts +110 -0
  51. package/src/lib/chart.ts +90 -0
  52. package/src/stories/area-chart.stories.tsx +198 -0
  53. package/src/stories/bar-chart.stories.tsx +167 -0
  54. package/src/stories/bar-list.stories.tsx +83 -0
  55. package/src/stories/donut-chart.stories.tsx +110 -0
  56. package/src/stories/heatmap-chart.stories.tsx +105 -0
  57. package/src/stories/line-chart.stories.tsx +144 -0
  58. package/src/stories/stat.stories.tsx +64 -0
  59. package/src/stories/wizard.stories.tsx +23 -5
  60. package/src/styles/tokens.css +18 -0
@@ -0,0 +1,64 @@
1
+ import { ChartSeries } from "../lib/chart.mjs";
2
+ import { ChartPaletteName } from "../lib/chart-palette.mjs";
3
+ import * as React$1 from "react";
4
+
5
+ //#region src/components/area-chart.d.ts
6
+ declare const CURVE_TYPE: {
7
+ readonly monotone: "monotone";
8
+ readonly linear: "linear";
9
+ readonly step: "stepAfter";
10
+ };
11
+ interface ChartMarker {
12
+ x: string | number;
13
+ y: number;
14
+ label?: string;
15
+ color?: string;
16
+ }
17
+ interface AreaChartProps {
18
+ data: ReadonlyArray<Record<string, string | number | null | undefined>>;
19
+ index: string;
20
+ series: ChartSeries[];
21
+ variant?: "stacked" | "grouped" | "expand";
22
+ curve?: keyof typeof CURVE_TYPE;
23
+ legend?: boolean;
24
+ legendAlign?: "left" | "center" | "right";
25
+ valueFlags?: boolean;
26
+ height?: number;
27
+ yAxisWidth?: number;
28
+ palette?: ChartPaletteName;
29
+ referenceLine?: {
30
+ y: number;
31
+ label?: string;
32
+ band?: boolean;
33
+ };
34
+ markers?: ChartMarker[];
35
+ lastValueLabel?: boolean;
36
+ texture?: boolean;
37
+ loading?: boolean;
38
+ valueFormatter?: (value: number) => string;
39
+ labelFormatter?: (label: string | number) => string;
40
+ className?: string;
41
+ }
42
+ declare function AreaChart({
43
+ data,
44
+ index,
45
+ series,
46
+ variant,
47
+ curve,
48
+ legend,
49
+ legendAlign,
50
+ valueFlags,
51
+ height,
52
+ yAxisWidth,
53
+ palette,
54
+ referenceLine,
55
+ markers,
56
+ lastValueLabel,
57
+ texture,
58
+ loading,
59
+ valueFormatter,
60
+ labelFormatter,
61
+ className
62
+ }: AreaChartProps): React$1.JSX.Element;
63
+ //#endregion
64
+ export { AreaChart, AreaChartProps, ChartMarker };
@@ -0,0 +1,275 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { useReducedMotion } from "../hooks/use-reduced-motion.mjs";
4
+ import { makeXAxisTick, orderByLuminance, resolveSeries } from "../lib/chart.mjs";
5
+ import { useChartContext } from "./chart-container.mjs";
6
+ import { ChartLegend } from "./chart-legend.mjs";
7
+ import { ChartTooltipContent } from "./chart-tooltip.mjs";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import * as React$1 from "react";
10
+ import { Area, AreaChart as AreaChart$1, CartesianGrid, LabelList, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
11
+ //#region src/components/area-chart.tsx
12
+ const CURVE_TYPE = {
13
+ monotone: "monotone",
14
+ linear: "linear",
15
+ step: "stepAfter"
16
+ };
17
+ function AreaChart({ data, index, series, variant = "stacked", curve = "monotone", legend = false, legendAlign = "left", valueFlags = false, height = 200, yAxisWidth = 48, palette, referenceLine, markers, lastValueLabel = false, texture = false, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, className }) {
18
+ const { palette: paletteColors, theme } = useChartContext(palette);
19
+ const reactId = React$1.useId().replace(/:/g, "");
20
+ const animated = !useReducedMotion();
21
+ const resolved = resolveSeries(series, paletteColors, theme);
22
+ const stacked = variant === "stacked" || variant === "expand";
23
+ const rendered = stacked ? orderByLuminance(resolved) : resolved;
24
+ const filled = !(variant === "grouped" && rendered.length > 1);
25
+ const lead = resolved[0];
26
+ const withTotal = stacked && rendered.length > 1;
27
+ const numericMax = React$1.useMemo(() => {
28
+ let max = 0;
29
+ for (const row of data) {
30
+ let rowTotal = 0;
31
+ for (const entry of series) {
32
+ const value = Number(row[entry.key]);
33
+ if (Number.isFinite(value)) {
34
+ rowTotal += value;
35
+ if (!stacked && value > max) max = value;
36
+ }
37
+ }
38
+ if (stacked && rowTotal > max) max = rowTotal;
39
+ }
40
+ return max;
41
+ }, [
42
+ data,
43
+ series,
44
+ stacked
45
+ ]);
46
+ const curveType = CURVE_TYPE[curve];
47
+ const margin = {
48
+ top: markers?.length ? 18 : 8,
49
+ right: lastValueLabel ? 56 : 8,
50
+ bottom: 2,
51
+ left: 0
52
+ };
53
+ const axis = {
54
+ stroke: theme.border,
55
+ tick: {
56
+ fill: theme.axisForeground,
57
+ fontSize: 10,
58
+ fontFamily: theme.fontMono
59
+ },
60
+ tickLine: false,
61
+ axisLine: {
62
+ stroke: theme.border,
63
+ strokeOpacity: .6
64
+ }
65
+ };
66
+ const legendItems = resolved.map((entry) => ({
67
+ name: entry.name,
68
+ color: entry.color,
69
+ dashed: entry.dashed
70
+ }));
71
+ const activeDotFor = (entry) => valueFlags ? (dotProps) => {
72
+ if (dotProps.cx == null || dotProps.cy == null) return /* @__PURE__ */ jsx("g", {});
73
+ return /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("circle", {
74
+ cx: dotProps.cx,
75
+ cy: dotProps.cy,
76
+ r: 3.5,
77
+ fill: entry.color,
78
+ stroke: theme.card,
79
+ strokeWidth: 2
80
+ }), /* @__PURE__ */ jsx("text", {
81
+ x: dotProps.cx,
82
+ y: dotProps.cy - 8,
83
+ textAnchor: "middle",
84
+ fill: entry.color,
85
+ fontFamily: theme.fontMono,
86
+ fontSize: 10,
87
+ style: { fontVariantNumeric: "tabular-nums" },
88
+ children: valueFormatter(Number(dotProps.value ?? 0))
89
+ })] });
90
+ } : {
91
+ r: 3.5,
92
+ fill: entry.color,
93
+ stroke: theme.card,
94
+ strokeWidth: 2
95
+ };
96
+ const fillFor = (entry, slot) => {
97
+ if (!filled) return "none";
98
+ if (texture && lead && entry.key === lead.key) return `url(#hatch-${reactId})`;
99
+ return `url(#area-${reactId}-${slot})`;
100
+ };
101
+ const renderLastLabel = (color) => (props) => {
102
+ if (props.index !== data.length - 1 || props.x == null || props.y == null) return null;
103
+ return /* @__PURE__ */ jsx("text", {
104
+ x: Number(props.x) + 6,
105
+ y: Number(props.y),
106
+ dy: 3,
107
+ fill: color,
108
+ fontFamily: theme.fontMono,
109
+ fontSize: 10,
110
+ textAnchor: "start",
111
+ style: { fontVariantNumeric: "tabular-nums" },
112
+ children: valueFormatter(Number(props.value ?? 0))
113
+ });
114
+ };
115
+ const isEmpty = data.length === 0 || rendered.length === 0;
116
+ return /* @__PURE__ */ jsxs("div", {
117
+ "data-slot": "area-chart",
118
+ className: cn("flex w-full flex-col gap-3", className),
119
+ children: [/* @__PURE__ */ jsx("div", {
120
+ className: "w-full",
121
+ style: { height },
122
+ children: loading ? /* @__PURE__ */ jsxs("div", {
123
+ className: "flex h-full items-center justify-center gap-2.5 font-mono text-quaternary-foreground text-text-xs",
124
+ children: [/* @__PURE__ */ jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-border border-t-foreground" }), "loading…"]
125
+ }) : isEmpty ? /* @__PURE__ */ jsx("div", {
126
+ className: "flex h-full items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs",
127
+ children: "no data in range"
128
+ }) : /* @__PURE__ */ jsx(ResponsiveContainer, {
129
+ width: "100%",
130
+ height: "100%",
131
+ initialDimension: {
132
+ width: 0,
133
+ height
134
+ },
135
+ children: /* @__PURE__ */ jsxs(AreaChart$1, {
136
+ data,
137
+ stackOffset: variant === "expand" ? "expand" : "none",
138
+ margin,
139
+ children: [
140
+ /* @__PURE__ */ jsxs("defs", { children: [filled && rendered.map((entry, slot) => /* @__PURE__ */ jsxs("linearGradient", {
141
+ id: `area-${reactId}-${slot}`,
142
+ x1: "0",
143
+ y1: "0",
144
+ x2: "0",
145
+ y2: "1",
146
+ children: [/* @__PURE__ */ jsx("stop", {
147
+ offset: "0%",
148
+ stopColor: entry.color,
149
+ stopOpacity: stacked ? .78 : .5
150
+ }), /* @__PURE__ */ jsx("stop", {
151
+ offset: "100%",
152
+ stopColor: entry.color,
153
+ stopOpacity: stacked ? .32 : .04
154
+ })]
155
+ }, entry.key)), texture && filled && lead && /* @__PURE__ */ jsxs("pattern", {
156
+ id: `hatch-${reactId}`,
157
+ patternUnits: "userSpaceOnUse",
158
+ width: 6,
159
+ height: 6,
160
+ patternTransform: "rotate(45)",
161
+ children: [/* @__PURE__ */ jsx("rect", {
162
+ width: 6,
163
+ height: 6,
164
+ fill: lead.color,
165
+ fillOpacity: .18
166
+ }), /* @__PURE__ */ jsx("line", {
167
+ x1: 0,
168
+ y1: 0,
169
+ x2: 0,
170
+ y2: 6,
171
+ stroke: lead.color,
172
+ strokeWidth: 1.2,
173
+ strokeOpacity: .6
174
+ })]
175
+ })] }),
176
+ /* @__PURE__ */ jsx(CartesianGrid, {
177
+ vertical: false,
178
+ stroke: theme.grid,
179
+ strokeDasharray: "2 4"
180
+ }),
181
+ /* @__PURE__ */ jsx(XAxis, {
182
+ dataKey: index,
183
+ ...axis,
184
+ tick: makeXAxisTick(theme),
185
+ interval: "preserveStartEnd",
186
+ minTickGap: 44
187
+ }),
188
+ /* @__PURE__ */ jsx(YAxis, {
189
+ ...axis,
190
+ width: yAxisWidth,
191
+ tickFormatter: (value) => variant === "expand" ? `${Math.round(value * 100)}%` : valueFormatter(value)
192
+ }),
193
+ /* @__PURE__ */ jsx(Tooltip, {
194
+ offset: 12,
195
+ allowEscapeViewBox: {
196
+ x: false,
197
+ y: false
198
+ },
199
+ cursor: {
200
+ stroke: theme.axisForeground,
201
+ strokeWidth: 1,
202
+ strokeDasharray: "3 3"
203
+ },
204
+ content: /* @__PURE__ */ jsx(ChartTooltipContent, {
205
+ valueFormatter,
206
+ labelFormatter,
207
+ showTotal: withTotal
208
+ })
209
+ }),
210
+ referenceLine?.band && /* @__PURE__ */ jsx(ReferenceArea, {
211
+ y1: referenceLine.y,
212
+ y2: numericMax,
213
+ fill: theme.warning,
214
+ fillOpacity: .06,
215
+ ifOverflow: "extendDomain"
216
+ }),
217
+ referenceLine && /* @__PURE__ */ jsx(ReferenceLine, {
218
+ y: referenceLine.y,
219
+ stroke: theme.warning,
220
+ strokeDasharray: "4 4",
221
+ strokeOpacity: .6,
222
+ label: referenceLine.label ? {
223
+ value: referenceLine.label,
224
+ fill: theme.warning,
225
+ fontSize: 9,
226
+ fontFamily: theme.fontMono,
227
+ position: "insideBottomRight"
228
+ } : void 0
229
+ }),
230
+ rendered.map((entry, slot) => /* @__PURE__ */ jsx(Area, {
231
+ type: curveType,
232
+ dataKey: entry.key,
233
+ name: entry.name,
234
+ stackId: stacked ? "stack" : void 0,
235
+ stroke: entry.color,
236
+ strokeWidth: entry.dashed ? 2 : 1.6,
237
+ strokeDasharray: entry.dashed ? "5 3" : void 0,
238
+ fill: fillFor(entry, slot),
239
+ dot: false,
240
+ activeDot: activeDotFor(entry),
241
+ isAnimationActive: animated,
242
+ animationDuration: 650,
243
+ animationEasing: "ease-out",
244
+ children: lastValueLabel && /* @__PURE__ */ jsx(LabelList, {
245
+ dataKey: entry.key,
246
+ content: renderLastLabel(entry.color)
247
+ })
248
+ }, entry.key)),
249
+ markers?.map((marker) => /* @__PURE__ */ jsx(ReferenceDot, {
250
+ x: marker.x,
251
+ y: marker.y,
252
+ r: 3.5,
253
+ fill: marker.color ?? theme.foreground,
254
+ stroke: theme.card,
255
+ strokeWidth: 2,
256
+ label: marker.label ? {
257
+ value: marker.label,
258
+ fill: marker.color ?? theme.foreground,
259
+ fontSize: 9,
260
+ fontFamily: theme.fontMono,
261
+ position: "top"
262
+ } : void 0
263
+ }, `${marker.x}-${marker.y}`))
264
+ ]
265
+ })
266
+ })
267
+ }), legend && !isEmpty && /* @__PURE__ */ jsx(ChartLegend, {
268
+ items: legendItems,
269
+ align: legendAlign,
270
+ insetLeft: yAxisWidth
271
+ })]
272
+ });
273
+ }
274
+ //#endregion
275
+ export { AreaChart };
@@ -0,0 +1,50 @@
1
+ import { ChartSeries } from "../lib/chart.mjs";
2
+ import { ChartPaletteName } from "../lib/chart-palette.mjs";
3
+ import { ChartMarker } from "./area-chart.mjs";
4
+ import * as React$1 from "react";
5
+
6
+ //#region src/components/bar-chart.d.ts
7
+ interface BarChartProps {
8
+ data: ReadonlyArray<Record<string, string | number | null | undefined>>;
9
+ index: string;
10
+ series: ChartSeries[];
11
+ variant?: "stacked" | "grouped" | "expand";
12
+ legend?: boolean;
13
+ legendAlign?: "left" | "center" | "right";
14
+ valueLabels?: boolean;
15
+ height?: number;
16
+ yAxisWidth?: number;
17
+ palette?: ChartPaletteName;
18
+ referenceLine?: {
19
+ y: number;
20
+ label?: string;
21
+ band?: boolean;
22
+ };
23
+ markers?: ChartMarker[];
24
+ texture?: boolean;
25
+ loading?: boolean;
26
+ valueFormatter?: (value: number) => string;
27
+ labelFormatter?: (label: string | number) => string;
28
+ className?: string;
29
+ }
30
+ declare function BarChart({
31
+ data,
32
+ index,
33
+ series,
34
+ variant,
35
+ legend,
36
+ legendAlign,
37
+ valueLabels,
38
+ height,
39
+ yAxisWidth,
40
+ palette,
41
+ referenceLine,
42
+ markers,
43
+ texture,
44
+ loading,
45
+ valueFormatter,
46
+ labelFormatter,
47
+ className
48
+ }: BarChartProps): React$1.JSX.Element;
49
+ //#endregion
50
+ export { BarChart, BarChartProps };
@@ -0,0 +1,262 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { useReducedMotion } from "../hooks/use-reduced-motion.mjs";
4
+ import { makeXAxisTick, orderByLuminance, resolveSeries } from "../lib/chart.mjs";
5
+ import { useChartContext } from "./chart-container.mjs";
6
+ import { ChartLegend } from "./chart-legend.mjs";
7
+ import { ChartTooltipContent } from "./chart-tooltip.mjs";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import * as React$1 from "react";
10
+ import { Bar, BarChart as BarChart$1, CartesianGrid, LabelList, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
11
+ //#region src/components/bar-chart.tsx
12
+ const BAR_RADIUS = 4;
13
+ const MAX_BAR_SIZE = 48;
14
+ function BarChart({ data, index, series, variant = "stacked", legend = false, legendAlign = "left", valueLabels = false, height = 200, yAxisWidth = 48, palette, referenceLine, markers, texture = false, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, className }) {
15
+ const { palette: paletteColors, theme } = useChartContext(palette);
16
+ const reactId = React$1.useId().replace(/:/g, "");
17
+ const animated = !useReducedMotion();
18
+ const resolved = resolveSeries(series, paletteColors, theme);
19
+ const stacked = variant === "stacked" || variant === "expand";
20
+ const rendered = stacked ? orderByLuminance(resolved) : resolved;
21
+ const lead = resolved[0];
22
+ const withTotal = stacked && rendered.length > 1;
23
+ const numericMax = React$1.useMemo(() => {
24
+ let max = 0;
25
+ for (const row of data) {
26
+ let rowTotal = 0;
27
+ for (const entry of series) {
28
+ const value = Number(row[entry.key]);
29
+ if (Number.isFinite(value)) {
30
+ rowTotal += value;
31
+ if (!stacked && value > max) max = value;
32
+ }
33
+ }
34
+ if (stacked && rowTotal > max) max = rowTotal;
35
+ }
36
+ return max;
37
+ }, [
38
+ data,
39
+ series,
40
+ stacked
41
+ ]);
42
+ const margin = {
43
+ top: markers?.length || valueLabels ? 18 : 8,
44
+ right: 8,
45
+ bottom: 2,
46
+ left: 0
47
+ };
48
+ const axis = {
49
+ stroke: theme.border,
50
+ tick: {
51
+ fill: theme.axisForeground,
52
+ fontSize: 10,
53
+ fontFamily: theme.fontMono
54
+ },
55
+ tickLine: false,
56
+ axisLine: {
57
+ stroke: theme.border,
58
+ strokeOpacity: .6
59
+ }
60
+ };
61
+ const legendItems = resolved.map((entry) => ({
62
+ name: entry.name,
63
+ color: entry.color,
64
+ dashed: entry.dashed
65
+ }));
66
+ const radiusFor = (slot) => {
67
+ if (!stacked || slot === rendered.length - 1) return [
68
+ BAR_RADIUS,
69
+ BAR_RADIUS,
70
+ 0,
71
+ 0
72
+ ];
73
+ return [
74
+ 0,
75
+ 0,
76
+ 0,
77
+ 0
78
+ ];
79
+ };
80
+ const fillFor = (entry, slot) => {
81
+ if (texture && lead && entry.key === lead.key) return `url(#bar-hatch-${reactId})`;
82
+ if (stacked) return entry.color;
83
+ return `url(#bar-${reactId}-${slot})`;
84
+ };
85
+ const renderValueLabel = (color) => (props) => {
86
+ if (props.x == null || props.y == null) return null;
87
+ return /* @__PURE__ */ jsx("text", {
88
+ x: Number(props.x) + Number(props.width ?? 0) / 2,
89
+ y: Number(props.y) - 5,
90
+ textAnchor: "middle",
91
+ fill: color,
92
+ fontFamily: theme.fontMono,
93
+ fontSize: 10,
94
+ style: { fontVariantNumeric: "tabular-nums" },
95
+ children: valueFormatter(Number(props.value ?? 0))
96
+ });
97
+ };
98
+ const isEmpty = data.length === 0 || rendered.length === 0;
99
+ return /* @__PURE__ */ jsxs("div", {
100
+ "data-slot": "bar-chart",
101
+ className: cn("flex w-full flex-col gap-3", className),
102
+ children: [/* @__PURE__ */ jsx("div", {
103
+ className: "w-full",
104
+ style: { height },
105
+ children: loading ? /* @__PURE__ */ jsxs("div", {
106
+ className: "flex h-full items-center justify-center gap-2.5 font-mono text-quaternary-foreground text-text-xs",
107
+ children: [/* @__PURE__ */ jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-border border-t-foreground" }), "loading…"]
108
+ }) : isEmpty ? /* @__PURE__ */ jsx("div", {
109
+ className: "flex h-full items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs",
110
+ children: "no data in range"
111
+ }) : /* @__PURE__ */ jsx(ResponsiveContainer, {
112
+ width: "100%",
113
+ height: "100%",
114
+ initialDimension: {
115
+ width: 0,
116
+ height
117
+ },
118
+ children: /* @__PURE__ */ jsxs(BarChart$1, {
119
+ data,
120
+ stackOffset: variant === "expand" ? "expand" : "none",
121
+ margin,
122
+ barCategoryGap: stacked ? "20%" : "16%",
123
+ children: [
124
+ /* @__PURE__ */ jsxs("defs", { children: [!stacked && rendered.map((entry, slot) => /* @__PURE__ */ jsxs("linearGradient", {
125
+ id: `bar-${reactId}-${slot}`,
126
+ x1: "0",
127
+ y1: "0",
128
+ x2: "0",
129
+ y2: "1",
130
+ children: [/* @__PURE__ */ jsx("stop", {
131
+ offset: "0%",
132
+ stopColor: entry.color,
133
+ stopOpacity: .95
134
+ }), /* @__PURE__ */ jsx("stop", {
135
+ offset: "100%",
136
+ stopColor: entry.color,
137
+ stopOpacity: .5
138
+ })]
139
+ }, entry.key)), texture && lead && /* @__PURE__ */ jsxs("pattern", {
140
+ id: `bar-hatch-${reactId}`,
141
+ patternUnits: "userSpaceOnUse",
142
+ width: 6,
143
+ height: 6,
144
+ patternTransform: "rotate(45)",
145
+ children: [/* @__PURE__ */ jsx("rect", {
146
+ width: 6,
147
+ height: 6,
148
+ fill: lead.color,
149
+ fillOpacity: .22
150
+ }), /* @__PURE__ */ jsx("line", {
151
+ x1: 0,
152
+ y1: 0,
153
+ x2: 0,
154
+ y2: 6,
155
+ stroke: lead.color,
156
+ strokeWidth: 1.2,
157
+ strokeOpacity: .65
158
+ })]
159
+ })] }),
160
+ /* @__PURE__ */ jsx(CartesianGrid, {
161
+ vertical: false,
162
+ stroke: theme.grid,
163
+ strokeDasharray: "2 4"
164
+ }),
165
+ /* @__PURE__ */ jsx(XAxis, {
166
+ dataKey: index,
167
+ ...axis,
168
+ tick: makeXAxisTick(theme),
169
+ interval: "preserveStartEnd",
170
+ minTickGap: 44
171
+ }),
172
+ /* @__PURE__ */ jsx(YAxis, {
173
+ ...axis,
174
+ width: yAxisWidth,
175
+ domain: referenceLine && variant !== "expand" ? [0, Math.ceil(Math.max(numericMax, referenceLine.y) * 1.15)] : void 0,
176
+ tickFormatter: (value) => variant === "expand" ? `${Math.round(value * 100)}%` : valueFormatter(value)
177
+ }),
178
+ /* @__PURE__ */ jsx(Tooltip, {
179
+ offset: 12,
180
+ allowEscapeViewBox: {
181
+ x: false,
182
+ y: false
183
+ },
184
+ cursor: {
185
+ fill: lead?.color ?? theme.mutedForeground,
186
+ fillOpacity: theme.isDark ? .1 : .06
187
+ },
188
+ content: /* @__PURE__ */ jsx(ChartTooltipContent, {
189
+ valueFormatter,
190
+ labelFormatter,
191
+ showTotal: withTotal
192
+ })
193
+ }),
194
+ referenceLine?.band && /* @__PURE__ */ jsx(ReferenceArea, {
195
+ y1: referenceLine.y,
196
+ y2: numericMax,
197
+ fill: theme.warning,
198
+ fillOpacity: .06,
199
+ ifOverflow: "extendDomain"
200
+ }),
201
+ referenceLine && /* @__PURE__ */ jsx(ReferenceLine, {
202
+ y: referenceLine.y,
203
+ stroke: theme.warning,
204
+ strokeDasharray: "4 4",
205
+ strokeOpacity: .6,
206
+ label: referenceLine.label ? {
207
+ value: referenceLine.label,
208
+ fill: theme.warning,
209
+ fontSize: 9,
210
+ fontFamily: theme.fontMono,
211
+ position: "insideBottomRight"
212
+ } : void 0
213
+ }),
214
+ rendered.map((entry, slot) => /* @__PURE__ */ jsx(Bar, {
215
+ dataKey: entry.key,
216
+ name: entry.name,
217
+ stackId: stacked ? "stack" : void 0,
218
+ fill: fillFor(entry, slot),
219
+ stroke: entry.color,
220
+ strokeWidth: 0,
221
+ radius: radiusFor(slot),
222
+ maxBarSize: MAX_BAR_SIZE,
223
+ activeBar: {
224
+ fillOpacity: 1,
225
+ stroke: theme.card,
226
+ strokeWidth: 1
227
+ },
228
+ isAnimationActive: animated,
229
+ animationDuration: 650,
230
+ animationEasing: "ease-out",
231
+ children: valueLabels && (!stacked || rendered.length === 1) && /* @__PURE__ */ jsx(LabelList, {
232
+ dataKey: entry.key,
233
+ content: renderValueLabel(entry.color)
234
+ })
235
+ }, entry.key)),
236
+ markers?.map((marker) => /* @__PURE__ */ jsx(ReferenceDot, {
237
+ x: marker.x,
238
+ y: marker.y,
239
+ r: 3.5,
240
+ fill: marker.color ?? theme.foreground,
241
+ stroke: theme.card,
242
+ strokeWidth: 2,
243
+ label: marker.label ? {
244
+ value: marker.label,
245
+ fill: marker.color ?? theme.foreground,
246
+ fontSize: 9,
247
+ fontFamily: theme.fontMono,
248
+ position: "top"
249
+ } : void 0
250
+ }, `${marker.x}-${marker.y}`))
251
+ ]
252
+ })
253
+ })
254
+ }), legend && !isEmpty && /* @__PURE__ */ jsx(ChartLegend, {
255
+ items: legendItems,
256
+ align: legendAlign,
257
+ insetLeft: yAxisWidth
258
+ })]
259
+ });
260
+ }
261
+ //#endregion
262
+ export { BarChart };
@@ -0,0 +1,31 @@
1
+ import { ChartPaletteName } from "../lib/chart-palette.mjs";
2
+ import * as React$1 from "react";
3
+
4
+ //#region src/components/bar-list.d.ts
5
+ interface BarListProps {
6
+ data: ReadonlyArray<Record<string, string | number | null | undefined>>;
7
+ index: string;
8
+ dataKey?: string;
9
+ maxItems?: number;
10
+ palette?: ChartPaletteName;
11
+ /** Renders bars in a single semantic hue (e.g. red for errors) rather than the palette ramp. */
12
+ semantic?: "error" | "warning" | "success";
13
+ loading?: boolean;
14
+ valueFormatter?: (value: number) => string;
15
+ labelFormatter?: (label: string | number) => string;
16
+ className?: string;
17
+ }
18
+ declare function BarList({
19
+ data,
20
+ index,
21
+ dataKey,
22
+ maxItems,
23
+ palette,
24
+ semantic,
25
+ loading,
26
+ valueFormatter,
27
+ labelFormatter,
28
+ className
29
+ }: BarListProps): React$1.JSX.Element;
30
+ //#endregion
31
+ export { BarList, BarListProps };