@geekmidas/ui 9.0.2 → 10.0.0-alpha.1

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 (106) hide show
  1. package/dist/button-BB4n8b0z.mjs +46 -0
  2. package/dist/button-BB4n8b0z.mjs.map +1 -0
  3. package/dist/button-BSp9VyHi.cjs +58 -0
  4. package/dist/button-BSp9VyHi.cjs.map +1 -0
  5. package/dist/chunk-CUT6urMc.cjs +30 -0
  6. package/dist/components/data-display/index.cjs +27 -0
  7. package/dist/components/data-display/index.d.cts +2 -0
  8. package/dist/components/data-display/index.d.mts +2 -0
  9. package/dist/components/data-display/index.mjs +6 -0
  10. package/dist/components/feedback/index.cjs +26 -0
  11. package/dist/components/feedback/index.d.cts +2 -0
  12. package/dist/components/feedback/index.d.mts +2 -0
  13. package/dist/components/feedback/index.mjs +6 -0
  14. package/dist/components/layout/index.cjs +26 -0
  15. package/dist/components/layout/index.d.cts +2 -0
  16. package/dist/components/layout/index.d.mts +2 -0
  17. package/dist/components/layout/index.mjs +6 -0
  18. package/dist/components/ui/index.cjs +73 -0
  19. package/dist/components/ui/index.d.cts +2 -0
  20. package/dist/components/ui/index.d.mts +2 -0
  21. package/dist/components/ui/index.mjs +7 -0
  22. package/dist/data-display-BSUj4rIc.cjs +1318 -0
  23. package/dist/data-display-BSUj4rIc.cjs.map +1 -0
  24. package/dist/data-display-IcuThGEY.mjs +1186 -0
  25. package/dist/data-display-IcuThGEY.mjs.map +1 -0
  26. package/dist/feedback-B9rTsQdJ.cjs +505 -0
  27. package/dist/feedback-B9rTsQdJ.cjs.map +1 -0
  28. package/dist/feedback-DBLrs44v.mjs +379 -0
  29. package/dist/feedback-DBLrs44v.mjs.map +1 -0
  30. package/dist/hooks/index.cjs +1 -1
  31. package/dist/hooks/index.d.cts +1 -1
  32. package/dist/hooks/index.d.mts +1 -1
  33. package/dist/hooks/index.mjs +1 -1
  34. package/dist/{hooks-DuxmSO-h.cjs → hooks-C5O7RXTd.cjs} +3 -31
  35. package/dist/{hooks-DuxmSO-h.cjs.map → hooks-C5O7RXTd.cjs.map} +1 -1
  36. package/dist/{hooks-DBc-Cw9X.mjs → hooks-Dhkovxbo.mjs} +1 -1
  37. package/dist/{hooks-DBc-Cw9X.mjs.map → hooks-Dhkovxbo.mjs.map} +1 -1
  38. package/dist/index-BHdsb44U.d.mts +102 -0
  39. package/dist/index-BHdsb44U.d.mts.map +1 -0
  40. package/dist/index-CBBJ6vmK.d.cts +154 -0
  41. package/dist/index-CBBJ6vmK.d.cts.map +1 -0
  42. package/dist/index-CcP4i-Xr.d.cts +102 -0
  43. package/dist/index-CcP4i-Xr.d.cts.map +1 -0
  44. package/dist/index-D4moB7PV.d.mts +153 -0
  45. package/dist/index-D4moB7PV.d.mts.map +1 -0
  46. package/dist/index-DDztdxvr.d.mts +329 -0
  47. package/dist/index-DDztdxvr.d.mts.map +1 -0
  48. package/dist/{index-DmtSyJ1q.d.mts → index-DTIa7Ryw.d.cts} +1 -1
  49. package/dist/{index-DmtSyJ1q.d.mts.map → index-DTIa7Ryw.d.cts.map} +1 -1
  50. package/dist/index-DsQW2bkf.d.mts +154 -0
  51. package/dist/index-DsQW2bkf.d.mts.map +1 -0
  52. package/dist/{index-QNnnyGjB.d.cts → index-DvzSne29.d.mts} +1 -1
  53. package/dist/{index-QNnnyGjB.d.cts.map → index-DvzSne29.d.mts.map} +1 -1
  54. package/dist/index-FnnlSxxr.d.cts +153 -0
  55. package/dist/index-FnnlSxxr.d.cts.map +1 -0
  56. package/dist/index-uRu0ad4_.d.cts +329 -0
  57. package/dist/index-uRu0ad4_.d.cts.map +1 -0
  58. package/dist/index.cjs +144 -2560
  59. package/dist/index.d.cts +8 -727
  60. package/dist/index.d.mts +8 -727
  61. package/dist/index.mjs +12 -2428
  62. package/dist/layout-CIIQOb1x.mjs +387 -0
  63. package/dist/layout-CIIQOb1x.mjs.map +1 -0
  64. package/dist/layout-CcO0svmw.cjs +513 -0
  65. package/dist/layout-CcO0svmw.cjs.map +1 -0
  66. package/dist/lib/utils.cjs +3 -0
  67. package/dist/lib/utils.d.cts +2 -0
  68. package/dist/lib/utils.d.mts +2 -0
  69. package/dist/lib/utils.mjs +3 -0
  70. package/dist/styles/theme.cjs +1 -1
  71. package/dist/styles/theme.d.cts +1 -1
  72. package/dist/styles/theme.d.mts +1 -1
  73. package/dist/styles/theme.mjs +1 -1
  74. package/dist/table-CrFSBSDe.mjs +129 -0
  75. package/dist/table-CrFSBSDe.mjs.map +1 -0
  76. package/dist/table-DNX6iqH5.cjs +237 -0
  77. package/dist/table-DNX6iqH5.cjs.map +1 -0
  78. package/dist/{theme-BRGSS8qx.cjs → theme-BBoDSysS.cjs} +1 -1
  79. package/dist/{theme-BRGSS8qx.cjs.map → theme-BBoDSysS.cjs.map} +1 -1
  80. package/dist/{theme-vpDwDfcR.d.mts → theme-BsXPj5m4.d.cts} +1 -1
  81. package/dist/{theme-B5mGkTlU.d.cts.map → theme-BsXPj5m4.d.cts.map} +1 -1
  82. package/dist/{theme-DAiFBbyM.mjs → theme-DI0sgbjj.mjs} +1 -1
  83. package/dist/{theme-DAiFBbyM.mjs.map → theme-DI0sgbjj.mjs.map} +1 -1
  84. package/dist/{theme-B5mGkTlU.d.cts → theme-aIIK_kn9.d.mts} +1 -1
  85. package/dist/{theme-vpDwDfcR.d.mts.map → theme-aIIK_kn9.d.mts.map} +1 -1
  86. package/dist/tooltip-BuTZvLTX.cjs +82 -0
  87. package/dist/tooltip-BuTZvLTX.cjs.map +1 -0
  88. package/dist/tooltip-z8o59BXq.mjs +46 -0
  89. package/dist/tooltip-z8o59BXq.mjs.map +1 -0
  90. package/dist/ui-B6Pj_ZAW.mjs +296 -0
  91. package/dist/ui-B6Pj_ZAW.mjs.map +1 -0
  92. package/dist/ui-PFNfvwdv.cjs +542 -0
  93. package/dist/ui-PFNfvwdv.cjs.map +1 -0
  94. package/dist/utils-0J5jzmnT.mjs +11 -0
  95. package/dist/utils-0J5jzmnT.mjs.map +1 -0
  96. package/dist/utils-3XfDEz8-.d.cts +9 -0
  97. package/dist/utils-3XfDEz8-.d.cts.map +1 -0
  98. package/dist/utils-CgSGIxhd.d.mts +9 -0
  99. package/dist/utils-CgSGIxhd.d.mts.map +1 -0
  100. package/dist/utils-DTuzb7hO.cjs +17 -0
  101. package/dist/utils-DTuzb7hO.cjs.map +1 -0
  102. package/package.json +1 -1
  103. package/dist/index.cjs.map +0 -1
  104. package/dist/index.d.cts.map +0 -1
  105. package/dist/index.d.mts.map +0 -1
  106. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,1186 @@
1
+ import { cn } from "./utils-0J5jzmnT.mjs";
2
+ import { Button } from "./button-BB4n8b0z.mjs";
3
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table-CrFSBSDe.mjs";
4
+ import { format, subDays, subHours } from "date-fns";
5
+ import { Area, AreaChart, Bar, BarChart, Cell, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { ArrowDown, ArrowUp, ArrowUpDown, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy } from "lucide-react";
8
+ import * as React from "react";
9
+ import { cva } from "class-variance-authority";
10
+
11
+ //#region src/components/data-display/charts/area-time-series-chart.tsx
12
+ const COLOR_MAP = {
13
+ blue: "hsl(217, 91%, 60%)",
14
+ red: "hsl(0, 84%, 60%)",
15
+ green: "hsl(142, 71%, 45%)",
16
+ amber: "hsl(38, 92%, 50%)",
17
+ purple: "hsl(263, 70%, 50%)"
18
+ };
19
+ function AreaTimeSeriesChart({ data, primaryLabel = "Value", secondaryLabel, primaryColor = "blue", secondaryColor = "red", timeFormat = "HH:mm", valueFormatter = (v) => v.toLocaleString(), className, showLegend }) {
20
+ if (data.length === 0) return /* @__PURE__ */ jsx("div", {
21
+ className: "h-48 flex items-center justify-center text-sm text-muted-foreground",
22
+ children: "No data available"
23
+ });
24
+ const hasSecondary = secondaryLabel && data.some((p) => p.secondaryValue !== void 0);
25
+ const chartData = data.map((point) => ({
26
+ time: format(new Date(point.timestamp), timeFormat),
27
+ timestamp: point.timestamp,
28
+ [primaryLabel]: point.value,
29
+ ...hasSecondary && secondaryLabel ? { [secondaryLabel]: point.secondaryValue ?? 0 } : {}
30
+ }));
31
+ const primaryColorValue = COLOR_MAP[primaryColor] ?? primaryColor;
32
+ const secondaryColorValue = COLOR_MAP[secondaryColor] ?? secondaryColor;
33
+ const shouldShowLegend = showLegend ?? hasSecondary;
34
+ return /* @__PURE__ */ jsxs("div", {
35
+ className: cn("h-48", className),
36
+ children: [/* @__PURE__ */ jsx(ResponsiveContainer, {
37
+ width: "100%",
38
+ height: "100%",
39
+ children: /* @__PURE__ */ jsxs(AreaChart, {
40
+ data: chartData,
41
+ children: [
42
+ /* @__PURE__ */ jsxs("defs", { children: [/* @__PURE__ */ jsxs("linearGradient", {
43
+ id: "primaryGradient",
44
+ x1: "0",
45
+ y1: "0",
46
+ x2: "0",
47
+ y2: "1",
48
+ children: [/* @__PURE__ */ jsx("stop", {
49
+ offset: "5%",
50
+ stopColor: primaryColorValue,
51
+ stopOpacity: .3
52
+ }), /* @__PURE__ */ jsx("stop", {
53
+ offset: "95%",
54
+ stopColor: primaryColorValue,
55
+ stopOpacity: 0
56
+ })]
57
+ }), hasSecondary && /* @__PURE__ */ jsxs("linearGradient", {
58
+ id: "secondaryGradient",
59
+ x1: "0",
60
+ y1: "0",
61
+ x2: "0",
62
+ y2: "1",
63
+ children: [/* @__PURE__ */ jsx("stop", {
64
+ offset: "5%",
65
+ stopColor: secondaryColorValue,
66
+ stopOpacity: .3
67
+ }), /* @__PURE__ */ jsx("stop", {
68
+ offset: "95%",
69
+ stopColor: secondaryColorValue,
70
+ stopOpacity: 0
71
+ })]
72
+ })] }),
73
+ /* @__PURE__ */ jsx(XAxis, {
74
+ dataKey: "time",
75
+ tick: {
76
+ fill: "hsl(var(--muted-foreground))",
77
+ fontSize: 12
78
+ },
79
+ axisLine: false,
80
+ tickLine: false
81
+ }),
82
+ /* @__PURE__ */ jsx(YAxis, {
83
+ tick: {
84
+ fill: "hsl(var(--muted-foreground))",
85
+ fontSize: 12
86
+ },
87
+ axisLine: false,
88
+ tickLine: false,
89
+ tickFormatter: valueFormatter,
90
+ width: 50
91
+ }),
92
+ /* @__PURE__ */ jsx(Tooltip, { content: ({ active, payload, label }) => {
93
+ if (!active || !payload?.length) return null;
94
+ return /* @__PURE__ */ jsxs("div", {
95
+ className: "rounded-lg border bg-popover px-3 py-2 text-sm shadow-md",
96
+ children: [/* @__PURE__ */ jsx("p", {
97
+ className: "font-medium mb-1",
98
+ children: label
99
+ }), payload.map((entry, index) => /* @__PURE__ */ jsxs("p", {
100
+ className: "flex items-center gap-2 text-muted-foreground",
101
+ children: [
102
+ /* @__PURE__ */ jsx("span", {
103
+ className: "w-2 h-2 rounded-full",
104
+ style: { backgroundColor: entry.color }
105
+ }),
106
+ entry.name,
107
+ ": ",
108
+ valueFormatter(entry.value)
109
+ ]
110
+ }, index))]
111
+ });
112
+ } }),
113
+ /* @__PURE__ */ jsx(Area, {
114
+ type: "monotone",
115
+ dataKey: primaryLabel,
116
+ stroke: primaryColorValue,
117
+ fill: "url(#primaryGradient)",
118
+ strokeWidth: 2
119
+ }),
120
+ hasSecondary && secondaryLabel && /* @__PURE__ */ jsx(Area, {
121
+ type: "monotone",
122
+ dataKey: secondaryLabel,
123
+ stroke: secondaryColorValue,
124
+ fill: "url(#secondaryGradient)",
125
+ strokeWidth: 2
126
+ })
127
+ ]
128
+ })
129
+ }), shouldShowLegend && /* @__PURE__ */ jsxs("div", {
130
+ className: "flex justify-center gap-4 mt-2",
131
+ children: [/* @__PURE__ */ jsxs("div", {
132
+ className: "flex items-center gap-2 text-xs",
133
+ children: [/* @__PURE__ */ jsx("div", {
134
+ className: "w-3 h-3 rounded-full",
135
+ style: { backgroundColor: primaryColorValue }
136
+ }), /* @__PURE__ */ jsx("span", {
137
+ className: "text-muted-foreground",
138
+ children: primaryLabel
139
+ })]
140
+ }), hasSecondary && secondaryLabel && /* @__PURE__ */ jsxs("div", {
141
+ className: "flex items-center gap-2 text-xs",
142
+ children: [/* @__PURE__ */ jsx("div", {
143
+ className: "w-3 h-3 rounded-full",
144
+ style: { backgroundColor: secondaryColorValue }
145
+ }), /* @__PURE__ */ jsx("span", {
146
+ className: "text-muted-foreground",
147
+ children: secondaryLabel
148
+ })]
149
+ })]
150
+ })]
151
+ });
152
+ }
153
+
154
+ //#endregion
155
+ //#region src/components/data-display/charts/bar-list-chart.tsx
156
+ function BarListChart({ data, valueFormatter = (v) => v.toLocaleString(), onItemClick, className, emptyMessage = "No data available", color = "hsl(217, 91%, 60%)" }) {
157
+ if (data.length === 0) return /* @__PURE__ */ jsx("div", {
158
+ className: "h-48 flex items-center justify-center text-sm text-muted-foreground",
159
+ children: emptyMessage
160
+ });
161
+ const maxValue = Math.max(...data.map((d) => d.value));
162
+ return /* @__PURE__ */ jsx("div", {
163
+ className: cn("space-y-3", className),
164
+ children: data.map((item, index) => {
165
+ const percentage = maxValue > 0 ? item.value / maxValue * 100 : 0;
166
+ const isClickable = !!onItemClick;
167
+ return /* @__PURE__ */ jsxs("div", {
168
+ className: cn("group", isClickable && "cursor-pointer"),
169
+ onClick: () => onItemClick?.(item),
170
+ children: [/* @__PURE__ */ jsxs("div", {
171
+ className: "flex items-center justify-between mb-1",
172
+ children: [/* @__PURE__ */ jsx("span", {
173
+ className: cn("text-sm truncate flex-1 mr-4", isClickable && "group-hover:text-foreground"),
174
+ children: item.name
175
+ }), /* @__PURE__ */ jsx("span", {
176
+ className: "text-sm font-medium tabular-nums",
177
+ children: valueFormatter(item.value)
178
+ })]
179
+ }), /* @__PURE__ */ jsx("div", {
180
+ className: "h-2 bg-muted rounded-full overflow-hidden",
181
+ children: /* @__PURE__ */ jsx("div", {
182
+ className: cn("h-full rounded-full transition-all duration-300", isClickable && "group-hover:opacity-80"),
183
+ style: {
184
+ width: `${percentage}%`,
185
+ backgroundColor: color
186
+ }
187
+ })
188
+ })]
189
+ }, index);
190
+ })
191
+ });
192
+ }
193
+
194
+ //#endregion
195
+ //#region src/components/data-display/charts/latency-percentiles-chart.tsx
196
+ function defaultFormatDuration(ms) {
197
+ if (ms < 1) return "<1ms";
198
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
199
+ return `${(ms / 1e3).toFixed(2)}s`;
200
+ }
201
+ const PERCENTILE_COLORS = {
202
+ p50: "hsl(217, 91%, 60%)",
203
+ p95: "hsl(38, 92%, 50%)",
204
+ p99: "hsl(0, 84%, 60%)"
205
+ };
206
+ function LatencyPercentilesChart({ p50, p95, p99, className, valueFormatter = defaultFormatDuration }) {
207
+ const chartData = [
208
+ {
209
+ name: "p50",
210
+ label: "p50 (Median)",
211
+ value: p50,
212
+ color: PERCENTILE_COLORS.p50
213
+ },
214
+ {
215
+ name: "p95",
216
+ label: "p95",
217
+ value: p95,
218
+ color: PERCENTILE_COLORS.p95
219
+ },
220
+ {
221
+ name: "p99",
222
+ label: "p99",
223
+ value: p99,
224
+ color: PERCENTILE_COLORS.p99
225
+ }
226
+ ];
227
+ if (p99 === 0) return /* @__PURE__ */ jsx("div", {
228
+ className: "h-48 flex items-center justify-center text-sm text-muted-foreground",
229
+ children: "No data available"
230
+ });
231
+ return /* @__PURE__ */ jsx("div", {
232
+ className: cn("h-48", className),
233
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, {
234
+ width: "100%",
235
+ height: "100%",
236
+ children: /* @__PURE__ */ jsxs(BarChart, {
237
+ data: chartData,
238
+ layout: "vertical",
239
+ barSize: 20,
240
+ children: [
241
+ /* @__PURE__ */ jsx(XAxis, {
242
+ type: "number",
243
+ tickFormatter: valueFormatter,
244
+ tick: {
245
+ fill: "hsl(var(--muted-foreground))",
246
+ fontSize: 12
247
+ },
248
+ axisLine: false,
249
+ tickLine: false
250
+ }),
251
+ /* @__PURE__ */ jsx(YAxis, {
252
+ type: "category",
253
+ dataKey: "label",
254
+ width: 90,
255
+ tick: {
256
+ fill: "hsl(var(--muted-foreground))",
257
+ fontSize: 12
258
+ },
259
+ axisLine: false,
260
+ tickLine: false
261
+ }),
262
+ /* @__PURE__ */ jsx(Tooltip, { content: ({ active, payload }) => {
263
+ if (!active || !payload?.length) return null;
264
+ const item = payload[0]?.payload;
265
+ return /* @__PURE__ */ jsxs("div", {
266
+ className: "rounded-lg border bg-popover px-3 py-2 text-sm shadow-md",
267
+ children: [/* @__PURE__ */ jsx("p", {
268
+ className: "font-medium",
269
+ children: item.label
270
+ }), /* @__PURE__ */ jsx("p", {
271
+ className: "text-muted-foreground",
272
+ children: valueFormatter(item.value)
273
+ })]
274
+ });
275
+ } }),
276
+ /* @__PURE__ */ jsx(Bar, {
277
+ dataKey: "value",
278
+ radius: [
279
+ 0,
280
+ 4,
281
+ 4,
282
+ 0
283
+ ],
284
+ children: chartData.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, `cell-${index}`))
285
+ })
286
+ ]
287
+ })
288
+ })
289
+ });
290
+ }
291
+
292
+ //#endregion
293
+ //#region src/components/data-display/charts/status-distribution-chart.tsx
294
+ const STATUS_CONFIG = {
295
+ "2xx": {
296
+ label: "2xx Success",
297
+ color: "hsl(142, 71%, 45%)"
298
+ },
299
+ "3xx": {
300
+ label: "3xx Redirect",
301
+ color: "hsl(217, 91%, 60%)"
302
+ },
303
+ "4xx": {
304
+ label: "4xx Client Error",
305
+ color: "hsl(38, 92%, 50%)"
306
+ },
307
+ "5xx": {
308
+ label: "5xx Server Error",
309
+ color: "hsl(0, 84%, 60%)"
310
+ }
311
+ };
312
+ function StatusDistributionChart({ data, className }) {
313
+ const chartData = Object.entries(data).filter(([, value]) => value > 0).map(([key, value]) => ({
314
+ name: STATUS_CONFIG[key].label,
315
+ value,
316
+ color: STATUS_CONFIG[key].color
317
+ }));
318
+ const total = chartData.reduce((sum, d) => sum + d.value, 0);
319
+ if (total === 0) return /* @__PURE__ */ jsx("div", {
320
+ className: "h-48 flex items-center justify-center text-sm text-muted-foreground",
321
+ children: "No data available"
322
+ });
323
+ return /* @__PURE__ */ jsxs("div", {
324
+ className: cn("h-48", className),
325
+ children: [/* @__PURE__ */ jsx(ResponsiveContainer, {
326
+ width: "100%",
327
+ height: "100%",
328
+ children: /* @__PURE__ */ jsxs(PieChart, { children: [/* @__PURE__ */ jsx(Pie, {
329
+ data: chartData,
330
+ cx: "50%",
331
+ cy: "50%",
332
+ innerRadius: 50,
333
+ outerRadius: 70,
334
+ paddingAngle: 2,
335
+ dataKey: "value",
336
+ nameKey: "name",
337
+ children: chartData.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, `cell-${index}`))
338
+ }), /* @__PURE__ */ jsx(Tooltip, { content: ({ active, payload }) => {
339
+ if (!active || !payload?.length) return null;
340
+ const item = payload[0];
341
+ const percent = (item.value / total * 100).toFixed(1);
342
+ return /* @__PURE__ */ jsxs("div", {
343
+ className: "rounded-lg border bg-popover px-3 py-2 text-sm shadow-md",
344
+ children: [/* @__PURE__ */ jsx("p", {
345
+ className: "font-medium",
346
+ children: item.name
347
+ }), /* @__PURE__ */ jsxs("p", {
348
+ className: "text-muted-foreground",
349
+ children: [
350
+ item.value.toLocaleString(),
351
+ " (",
352
+ percent,
353
+ "%)"
354
+ ]
355
+ })]
356
+ });
357
+ } })] })
358
+ }), /* @__PURE__ */ jsx("div", {
359
+ className: "flex flex-wrap justify-center gap-4 mt-2",
360
+ children: chartData.map((item) => /* @__PURE__ */ jsxs("div", {
361
+ className: "flex items-center gap-2 text-xs",
362
+ children: [/* @__PURE__ */ jsx("div", {
363
+ className: "w-3 h-3 rounded-full",
364
+ style: { backgroundColor: item.color }
365
+ }), /* @__PURE__ */ jsx("span", {
366
+ className: "text-muted-foreground",
367
+ children: item.name
368
+ })]
369
+ }, item.name))
370
+ })]
371
+ });
372
+ }
373
+
374
+ //#endregion
375
+ //#region src/components/data-display/charts/time-range-selector.tsx
376
+ const defaultPresets = [
377
+ {
378
+ label: "1h",
379
+ value: "1h"
380
+ },
381
+ {
382
+ label: "6h",
383
+ value: "6h"
384
+ },
385
+ {
386
+ label: "24h",
387
+ value: "24h"
388
+ },
389
+ {
390
+ label: "7d",
391
+ value: "7d"
392
+ }
393
+ ];
394
+ function getPresetRange(preset) {
395
+ const end = /* @__PURE__ */ new Date();
396
+ switch (preset) {
397
+ case "1h": return {
398
+ start: subHours(end, 1),
399
+ end
400
+ };
401
+ case "6h": return {
402
+ start: subHours(end, 6),
403
+ end
404
+ };
405
+ case "24h": return {
406
+ start: subHours(end, 24),
407
+ end
408
+ };
409
+ case "7d": return {
410
+ start: subDays(end, 7),
411
+ end
412
+ };
413
+ default: return {
414
+ start: subHours(end, 1),
415
+ end
416
+ };
417
+ }
418
+ }
419
+ function TimeRangeSelector({ value, onChange, presets = defaultPresets, className }) {
420
+ const handlePresetClick = (preset) => {
421
+ const range = getPresetRange(preset);
422
+ onChange({
423
+ preset,
424
+ ...range
425
+ });
426
+ };
427
+ return /* @__PURE__ */ jsx("div", {
428
+ className: cn("flex items-center gap-2", className),
429
+ children: /* @__PURE__ */ jsx("div", {
430
+ className: "flex rounded-md border border-border overflow-hidden",
431
+ children: presets.map(({ label, value: preset }, index) => /* @__PURE__ */ jsx("button", {
432
+ type: "button",
433
+ onClick: () => handlePresetClick(preset),
434
+ className: cn("px-3 py-1.5 text-sm font-medium transition-colors", value.preset === preset ? "bg-primary text-primary-foreground" : "bg-card hover:bg-muted text-foreground", index > 0 && "border-l border-border"),
435
+ children: label
436
+ }, preset))
437
+ })
438
+ });
439
+ }
440
+ /**
441
+ * Create a time range from a preset
442
+ */
443
+ function createTimeRange(preset = "1h") {
444
+ const range = getPresetRange(preset);
445
+ return {
446
+ preset,
447
+ ...range
448
+ };
449
+ }
450
+
451
+ //#endregion
452
+ //#region src/components/data-display/data-table.tsx
453
+ function DataTableInner({ className, columns, data, getRowKey = (_, index) => index, sortColumn, sortDirection, onSortChange, pagination = false, page = 1, pageSize = 10, totalItems, onPageChange, onPageSizeChange, pageSizeOptions = [
454
+ 10,
455
+ 20,
456
+ 50,
457
+ 100
458
+ ], loading = false, emptyState, onRowClick, selectedKeys, striped = false, hoverable = true, compact = false,...props }, ref) {
459
+ const total = totalItems ?? data.length;
460
+ const totalPages = Math.ceil(total / pageSize);
461
+ const handleSort = (columnKey) => {
462
+ if (!onSortChange) return;
463
+ if (sortColumn === columnKey) onSortChange(columnKey, sortDirection === "asc" ? "desc" : "asc");
464
+ else onSortChange(columnKey, "asc");
465
+ };
466
+ const getSortIcon = (columnKey) => {
467
+ if (sortColumn !== columnKey) return /* @__PURE__ */ jsx(ArrowUpDown, { className: "ml-1 h-3.5 w-3.5 text-muted-foreground" });
468
+ return sortDirection === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "ml-1 h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ArrowDown, { className: "ml-1 h-3.5 w-3.5" });
469
+ };
470
+ const getAlignClass = (align) => {
471
+ switch (align) {
472
+ case "center": return "text-center";
473
+ case "right": return "text-right";
474
+ default: return "text-left";
475
+ }
476
+ };
477
+ return /* @__PURE__ */ jsxs("div", {
478
+ ref,
479
+ className: cn("w-full", className),
480
+ ...props,
481
+ children: [/* @__PURE__ */ jsx("div", {
482
+ className: "rounded-md border border-border overflow-hidden",
483
+ children: /* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, {
484
+ className: "hover:bg-transparent",
485
+ children: columns.map((column) => /* @__PURE__ */ jsx(TableHead, {
486
+ className: cn(getAlignClass(column.align), column.sortable && "cursor-pointer select-none", compact ? "py-2" : "py-3", column.headerClassName),
487
+ style: { width: column.width },
488
+ onClick: column.sortable ? () => handleSort(column.key) : void 0,
489
+ children: /* @__PURE__ */ jsxs("div", {
490
+ className: cn("flex items-center", column.align === "center" && "justify-center", column.align === "right" && "justify-end"),
491
+ children: [column.header, column.sortable && getSortIcon(column.key)]
492
+ })
493
+ }, column.key))
494
+ }) }), /* @__PURE__ */ jsx(TableBody, { children: loading ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
495
+ colSpan: columns.length,
496
+ className: "h-24 text-center text-muted-foreground",
497
+ children: "Loading..."
498
+ }) }) : data.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
499
+ colSpan: columns.length,
500
+ className: "h-24 text-center text-muted-foreground",
501
+ children: emptyState ?? "No data available"
502
+ }) }) : data.map((row, rowIndex) => {
503
+ const rowKey = getRowKey(row, rowIndex);
504
+ const isSelected = selectedKeys?.has(rowKey);
505
+ return /* @__PURE__ */ jsx(TableRow, {
506
+ className: cn(striped && rowIndex % 2 === 1 && "bg-surface/50", hoverable && "hover:bg-surface-hover cursor-pointer", isSelected && "bg-accent/10", onRowClick && "cursor-pointer"),
507
+ onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
508
+ children: columns.map((column) => /* @__PURE__ */ jsx(TableCell, {
509
+ className: cn(getAlignClass(column.align), compact ? "py-2" : "py-3", column.cellClassName),
510
+ children: column.cell ? column.cell(row, rowIndex) : column.accessor ? column.accessor(row) : row[column.key]
511
+ }, column.key))
512
+ }, rowKey);
513
+ }) })] })
514
+ }), pagination && totalPages > 0 && /* @__PURE__ */ jsxs("div", {
515
+ className: "flex items-center justify-between px-2 py-4",
516
+ children: [/* @__PURE__ */ jsxs("div", {
517
+ className: "flex items-center gap-2 text-sm text-muted-foreground",
518
+ children: [/* @__PURE__ */ jsx("span", { children: "Rows per page:" }), /* @__PURE__ */ jsxs(Select, {
519
+ value: String(pageSize),
520
+ onValueChange: (value) => onPageSizeChange?.(Number(value)),
521
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
522
+ className: "h-8 w-[70px]",
523
+ children: /* @__PURE__ */ jsx(SelectValue, {})
524
+ }), /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx(SelectItem, {
525
+ value: String(size),
526
+ children: size
527
+ }, size)) })]
528
+ })]
529
+ }), /* @__PURE__ */ jsxs("div", {
530
+ className: "flex items-center gap-2",
531
+ children: [/* @__PURE__ */ jsxs("span", {
532
+ className: "text-sm text-muted-foreground",
533
+ children: [
534
+ "Page ",
535
+ page,
536
+ " of ",
537
+ totalPages
538
+ ]
539
+ }), /* @__PURE__ */ jsxs("div", {
540
+ className: "flex items-center gap-1",
541
+ children: [
542
+ /* @__PURE__ */ jsx(Button, {
543
+ variant: "outline",
544
+ size: "icon",
545
+ className: "h-8 w-8",
546
+ onClick: () => onPageChange?.(1),
547
+ disabled: page <= 1,
548
+ children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
549
+ }),
550
+ /* @__PURE__ */ jsx(Button, {
551
+ variant: "outline",
552
+ size: "icon",
553
+ className: "h-8 w-8",
554
+ onClick: () => onPageChange?.(page - 1),
555
+ disabled: page <= 1,
556
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
557
+ }),
558
+ /* @__PURE__ */ jsx(Button, {
559
+ variant: "outline",
560
+ size: "icon",
561
+ className: "h-8 w-8",
562
+ onClick: () => onPageChange?.(page + 1),
563
+ disabled: page >= totalPages,
564
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
565
+ }),
566
+ /* @__PURE__ */ jsx(Button, {
567
+ variant: "outline",
568
+ size: "icon",
569
+ className: "h-8 w-8",
570
+ onClick: () => onPageChange?.(totalPages),
571
+ disabled: page >= totalPages,
572
+ children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
573
+ })
574
+ ]
575
+ })]
576
+ })]
577
+ })]
578
+ });
579
+ }
580
+ const DataTable = React.forwardRef(DataTableInner);
581
+
582
+ //#endregion
583
+ //#region src/components/data-display/json-viewer.tsx
584
+ const JsonViewer = React.forwardRef(({ className, data, defaultExpanded = true, expandDepth = 2, copyable = true, keyClassName, valueClassName,...props }, ref) => {
585
+ const [copied, setCopied] = React.useState(false);
586
+ const handleCopy = async () => {
587
+ await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
588
+ setCopied(true);
589
+ setTimeout(() => setCopied(false), 2e3);
590
+ };
591
+ return /* @__PURE__ */ jsxs("div", {
592
+ ref,
593
+ className: cn("relative rounded-md bg-surface border border-border font-mono text-sm", className),
594
+ ...props,
595
+ children: [copyable && /* @__PURE__ */ jsx("button", {
596
+ type: "button",
597
+ onClick: handleCopy,
598
+ className: "absolute right-2 top-2 p-1.5 rounded-md hover:bg-surface-hover text-muted-foreground hover:text-foreground transition-colors",
599
+ "aria-label": "Copy JSON",
600
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-green-500" }) : /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
601
+ }), /* @__PURE__ */ jsx("div", {
602
+ className: "p-3 overflow-auto",
603
+ children: /* @__PURE__ */ jsx(JsonNode, {
604
+ data,
605
+ depth: 0,
606
+ defaultExpanded,
607
+ expandDepth,
608
+ keyClassName,
609
+ valueClassName
610
+ })
611
+ })]
612
+ });
613
+ });
614
+ JsonViewer.displayName = "JsonViewer";
615
+ function JsonNode({ data, depth, defaultExpanded, expandDepth, keyClassName, valueClassName, propertyKey, isLast = true }) {
616
+ const [expanded, setExpanded] = React.useState(defaultExpanded && depth < expandDepth);
617
+ const indent = depth * 16;
618
+ if (data === null) return /* @__PURE__ */ jsxs("span", {
619
+ className: "inline",
620
+ children: [
621
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
622
+ className: cn("text-purple-400", keyClassName),
623
+ children: [
624
+ "\"",
625
+ propertyKey,
626
+ "\""
627
+ ]
628
+ }), /* @__PURE__ */ jsx("span", {
629
+ className: "text-muted-foreground",
630
+ children: ": "
631
+ })] }),
632
+ /* @__PURE__ */ jsx("span", {
633
+ className: cn("text-orange-400", valueClassName),
634
+ children: "null"
635
+ }),
636
+ !isLast && /* @__PURE__ */ jsx("span", {
637
+ className: "text-muted-foreground",
638
+ children: ","
639
+ })
640
+ ]
641
+ });
642
+ if (data === void 0) return /* @__PURE__ */ jsxs("span", {
643
+ className: "inline",
644
+ children: [
645
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
646
+ className: cn("text-purple-400", keyClassName),
647
+ children: [
648
+ "\"",
649
+ propertyKey,
650
+ "\""
651
+ ]
652
+ }), /* @__PURE__ */ jsx("span", {
653
+ className: "text-muted-foreground",
654
+ children: ": "
655
+ })] }),
656
+ /* @__PURE__ */ jsx("span", {
657
+ className: cn("text-gray-500", valueClassName),
658
+ children: "undefined"
659
+ }),
660
+ !isLast && /* @__PURE__ */ jsx("span", {
661
+ className: "text-muted-foreground",
662
+ children: ","
663
+ })
664
+ ]
665
+ });
666
+ if (typeof data === "boolean") return /* @__PURE__ */ jsxs("span", {
667
+ className: "inline",
668
+ children: [
669
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
670
+ className: cn("text-purple-400", keyClassName),
671
+ children: [
672
+ "\"",
673
+ propertyKey,
674
+ "\""
675
+ ]
676
+ }), /* @__PURE__ */ jsx("span", {
677
+ className: "text-muted-foreground",
678
+ children: ": "
679
+ })] }),
680
+ /* @__PURE__ */ jsx("span", {
681
+ className: cn("text-blue-400", valueClassName),
682
+ children: String(data)
683
+ }),
684
+ !isLast && /* @__PURE__ */ jsx("span", {
685
+ className: "text-muted-foreground",
686
+ children: ","
687
+ })
688
+ ]
689
+ });
690
+ if (typeof data === "number") return /* @__PURE__ */ jsxs("span", {
691
+ className: "inline",
692
+ children: [
693
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
694
+ className: cn("text-purple-400", keyClassName),
695
+ children: [
696
+ "\"",
697
+ propertyKey,
698
+ "\""
699
+ ]
700
+ }), /* @__PURE__ */ jsx("span", {
701
+ className: "text-muted-foreground",
702
+ children: ": "
703
+ })] }),
704
+ /* @__PURE__ */ jsx("span", {
705
+ className: cn("text-amber-400", valueClassName),
706
+ children: data
707
+ }),
708
+ !isLast && /* @__PURE__ */ jsx("span", {
709
+ className: "text-muted-foreground",
710
+ children: ","
711
+ })
712
+ ]
713
+ });
714
+ if (typeof data === "string") return /* @__PURE__ */ jsxs("span", {
715
+ className: "inline",
716
+ children: [
717
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
718
+ className: cn("text-purple-400", keyClassName),
719
+ children: [
720
+ "\"",
721
+ propertyKey,
722
+ "\""
723
+ ]
724
+ }), /* @__PURE__ */ jsx("span", {
725
+ className: "text-muted-foreground",
726
+ children: ": "
727
+ })] }),
728
+ /* @__PURE__ */ jsxs("span", {
729
+ className: cn("text-green-400", valueClassName),
730
+ children: [
731
+ "\"",
732
+ data,
733
+ "\""
734
+ ]
735
+ }),
736
+ !isLast && /* @__PURE__ */ jsx("span", {
737
+ className: "text-muted-foreground",
738
+ children: ","
739
+ })
740
+ ]
741
+ });
742
+ if (Array.isArray(data)) {
743
+ if (data.length === 0) return /* @__PURE__ */ jsxs("span", {
744
+ className: "inline",
745
+ children: [
746
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
747
+ className: cn("text-purple-400", keyClassName),
748
+ children: [
749
+ "\"",
750
+ propertyKey,
751
+ "\""
752
+ ]
753
+ }), /* @__PURE__ */ jsx("span", {
754
+ className: "text-muted-foreground",
755
+ children: ": "
756
+ })] }),
757
+ /* @__PURE__ */ jsx("span", {
758
+ className: "text-muted-foreground",
759
+ children: "[]"
760
+ }),
761
+ !isLast && /* @__PURE__ */ jsx("span", {
762
+ className: "text-muted-foreground",
763
+ children: ","
764
+ })
765
+ ]
766
+ });
767
+ return /* @__PURE__ */ jsxs("div", {
768
+ className: "inline-block",
769
+ children: [
770
+ /* @__PURE__ */ jsxs("span", {
771
+ className: "inline-flex items-center cursor-pointer hover:text-foreground text-muted-foreground",
772
+ onClick: () => setExpanded(!expanded),
773
+ children: [
774
+ expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 mr-0.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 mr-0.5" }),
775
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
776
+ className: cn("text-purple-400", keyClassName),
777
+ children: [
778
+ "\"",
779
+ propertyKey,
780
+ "\""
781
+ ]
782
+ }), /* @__PURE__ */ jsx("span", {
783
+ className: "text-muted-foreground",
784
+ children: ": "
785
+ })] }),
786
+ /* @__PURE__ */ jsx("span", {
787
+ className: "text-muted-foreground",
788
+ children: "["
789
+ }),
790
+ !expanded && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
791
+ className: "text-muted-foreground mx-1",
792
+ children: [data.length, " items"]
793
+ }), /* @__PURE__ */ jsx("span", {
794
+ className: "text-muted-foreground",
795
+ children: "]"
796
+ })] })
797
+ ]
798
+ }),
799
+ expanded && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
800
+ style: { paddingLeft: indent + 16 },
801
+ children: data.map((item, index) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(JsonNode, {
802
+ data: item,
803
+ depth: depth + 1,
804
+ defaultExpanded,
805
+ expandDepth,
806
+ keyClassName,
807
+ valueClassName,
808
+ isLast: index === data.length - 1
809
+ }) }, index))
810
+ }), /* @__PURE__ */ jsx("span", {
811
+ className: "text-muted-foreground",
812
+ children: "]"
813
+ })] }),
814
+ !isLast && /* @__PURE__ */ jsx("span", {
815
+ className: "text-muted-foreground",
816
+ children: ","
817
+ })
818
+ ]
819
+ });
820
+ }
821
+ if (typeof data === "object") {
822
+ const entries = Object.entries(data);
823
+ if (entries.length === 0) return /* @__PURE__ */ jsxs("span", {
824
+ className: "inline",
825
+ children: [
826
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
827
+ className: cn("text-purple-400", keyClassName),
828
+ children: [
829
+ "\"",
830
+ propertyKey,
831
+ "\""
832
+ ]
833
+ }), /* @__PURE__ */ jsx("span", {
834
+ className: "text-muted-foreground",
835
+ children: ": "
836
+ })] }),
837
+ /* @__PURE__ */ jsx("span", {
838
+ className: "text-muted-foreground",
839
+ children: "{}"
840
+ }),
841
+ !isLast && /* @__PURE__ */ jsx("span", {
842
+ className: "text-muted-foreground",
843
+ children: ","
844
+ })
845
+ ]
846
+ });
847
+ return /* @__PURE__ */ jsxs("div", {
848
+ className: "inline-block",
849
+ children: [
850
+ /* @__PURE__ */ jsxs("span", {
851
+ className: "inline-flex items-center cursor-pointer hover:text-foreground text-muted-foreground",
852
+ onClick: () => setExpanded(!expanded),
853
+ children: [
854
+ expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 mr-0.5" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 mr-0.5" }),
855
+ propertyKey && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
856
+ className: cn("text-purple-400", keyClassName),
857
+ children: [
858
+ "\"",
859
+ propertyKey,
860
+ "\""
861
+ ]
862
+ }), /* @__PURE__ */ jsx("span", {
863
+ className: "text-muted-foreground",
864
+ children: ": "
865
+ })] }),
866
+ /* @__PURE__ */ jsx("span", {
867
+ className: "text-muted-foreground",
868
+ children: "{"
869
+ }),
870
+ !expanded && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
871
+ className: "text-muted-foreground mx-1",
872
+ children: "..."
873
+ }), /* @__PURE__ */ jsx("span", {
874
+ className: "text-muted-foreground",
875
+ children: "}"
876
+ })] })
877
+ ]
878
+ }),
879
+ expanded && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
880
+ style: { paddingLeft: indent + 16 },
881
+ children: entries.map(([key, value], index) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(JsonNode, {
882
+ data: value,
883
+ depth: depth + 1,
884
+ defaultExpanded,
885
+ expandDepth,
886
+ keyClassName,
887
+ valueClassName,
888
+ propertyKey: key,
889
+ isLast: index === entries.length - 1
890
+ }) }, key))
891
+ }), /* @__PURE__ */ jsx("span", {
892
+ className: "text-muted-foreground",
893
+ children: "}"
894
+ })] }),
895
+ !isLast && /* @__PURE__ */ jsx("span", {
896
+ className: "text-muted-foreground",
897
+ children: ","
898
+ })
899
+ ]
900
+ });
901
+ }
902
+ return /* @__PURE__ */ jsx("span", {
903
+ className: cn("text-muted-foreground", valueClassName),
904
+ children: String(data)
905
+ });
906
+ }
907
+
908
+ //#endregion
909
+ //#region src/components/data-display/sparkline.tsx
910
+ const Sparkline = React.forwardRef(({ className, data, width = 100, height = 32, color = "currentColor", strokeWidth = 2, filled = false, fillOpacity = .2, showDots = false, curved = true, min: minProp, max: maxProp,...props }, ref) => {
911
+ if (data.length === 0) return /* @__PURE__ */ jsx("svg", {
912
+ ref,
913
+ className: cn("text-accent", className),
914
+ width,
915
+ height,
916
+ viewBox: `0 0 ${width} ${height}`,
917
+ ...props
918
+ });
919
+ const min = minProp ?? Math.min(...data);
920
+ const max = maxProp ?? Math.max(...data);
921
+ const range = max - min || 1;
922
+ const padding = strokeWidth;
923
+ const chartWidth = width - padding * 2;
924
+ const chartHeight = height - padding * 2;
925
+ const points = data.map((value, index) => {
926
+ const x = padding + index / (data.length - 1 || 1) * chartWidth;
927
+ const y = padding + chartHeight - (value - min) / range * chartHeight;
928
+ return {
929
+ x,
930
+ y
931
+ };
932
+ });
933
+ let pathD;
934
+ if (curved && points.length > 2) pathD = points.reduce((acc, point, index) => {
935
+ if (index === 0) return `M ${point.x},${point.y}`;
936
+ const prev = points[index - 1];
937
+ const cpX = (prev.x + point.x) / 2;
938
+ return `${acc} Q ${prev.x},${prev.y} ${cpX},${(prev.y + point.y) / 2} T ${point.x},${point.y}`;
939
+ }, "");
940
+ else pathD = points.map((point, index) => index === 0 ? `M ${point.x},${point.y}` : `L ${point.x},${point.y}`).join(" ");
941
+ const fillPathD = filled ? `${pathD} L ${points[points.length - 1]?.x},${height - padding} L ${points[0]?.x},${height - padding} Z` : "";
942
+ return /* @__PURE__ */ jsxs("svg", {
943
+ ref,
944
+ className: cn("text-accent", className),
945
+ width,
946
+ height,
947
+ viewBox: `0 0 ${width} ${height}`,
948
+ ...props,
949
+ children: [
950
+ filled && /* @__PURE__ */ jsx("path", {
951
+ d: fillPathD,
952
+ fill: color,
953
+ opacity: fillOpacity,
954
+ strokeWidth: 0
955
+ }),
956
+ /* @__PURE__ */ jsx("path", {
957
+ d: pathD,
958
+ fill: "none",
959
+ stroke: color,
960
+ strokeWidth,
961
+ strokeLinecap: "round",
962
+ strokeLinejoin: "round"
963
+ }),
964
+ showDots && points.map((point, index) => /* @__PURE__ */ jsx("circle", {
965
+ cx: point.x,
966
+ cy: point.y,
967
+ r: strokeWidth + 1,
968
+ fill: color
969
+ }, index))
970
+ ]
971
+ });
972
+ });
973
+ Sparkline.displayName = "Sparkline";
974
+ const SparkBar = React.forwardRef(({ className, data, width = 100, height = 32, color = "currentColor", gap = .2, min: minProp = 0, max: maxProp, radius = 2,...props }, ref) => {
975
+ if (data.length === 0) return /* @__PURE__ */ jsx("svg", {
976
+ ref,
977
+ className: cn("text-accent", className),
978
+ width,
979
+ height,
980
+ viewBox: `0 0 ${width} ${height}`,
981
+ ...props
982
+ });
983
+ const min = minProp;
984
+ const max = maxProp ?? Math.max(...data);
985
+ const range = max - min || 1;
986
+ const barWidth = width / data.length;
987
+ const gapWidth = barWidth * gap;
988
+ const actualBarWidth = barWidth - gapWidth;
989
+ return /* @__PURE__ */ jsx("svg", {
990
+ ref,
991
+ className: cn("text-accent", className),
992
+ width,
993
+ height,
994
+ viewBox: `0 0 ${width} ${height}`,
995
+ ...props,
996
+ children: data.map((value, index) => {
997
+ const barHeight = (value - min) / range * height;
998
+ const x = index * barWidth + gapWidth / 2;
999
+ const y = height - barHeight;
1000
+ return /* @__PURE__ */ jsx("rect", {
1001
+ x,
1002
+ y,
1003
+ width: actualBarWidth,
1004
+ height: barHeight,
1005
+ fill: color,
1006
+ rx: radius,
1007
+ ry: radius
1008
+ }, index);
1009
+ })
1010
+ });
1011
+ });
1012
+ SparkBar.displayName = "SparkBar";
1013
+ const MetricCard = React.forwardRef(({ className, title, value, description, sparklineData, trend, trendValue, icon,...props }, ref) => {
1014
+ const trendColor = trend === "up" ? "text-green-500" : trend === "down" ? "text-red-500" : "text-muted-foreground";
1015
+ return /* @__PURE__ */ jsxs("div", {
1016
+ ref,
1017
+ className: cn("rounded-lg border border-border bg-surface p-4", className),
1018
+ ...props,
1019
+ children: [/* @__PURE__ */ jsxs("div", {
1020
+ className: "flex items-center justify-between",
1021
+ children: [/* @__PURE__ */ jsx("span", {
1022
+ className: "text-sm font-medium text-muted-foreground",
1023
+ children: title
1024
+ }), icon && /* @__PURE__ */ jsx("span", {
1025
+ className: "text-muted-foreground",
1026
+ children: icon
1027
+ })]
1028
+ }), /* @__PURE__ */ jsxs("div", {
1029
+ className: "mt-2 flex items-end justify-between",
1030
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
1031
+ className: "text-2xl font-bold text-foreground",
1032
+ children: value
1033
+ }), (description || trendValue) && /* @__PURE__ */ jsxs("div", {
1034
+ className: "mt-1 flex items-center gap-1",
1035
+ children: [trendValue && /* @__PURE__ */ jsx("span", {
1036
+ className: cn("text-xs font-medium", trendColor),
1037
+ children: trendValue
1038
+ }), description && /* @__PURE__ */ jsx("span", {
1039
+ className: "text-xs text-muted-foreground",
1040
+ children: description
1041
+ })]
1042
+ })] }), sparklineData && sparklineData.length > 0 && /* @__PURE__ */ jsx(Sparkline, {
1043
+ data: sparklineData,
1044
+ width: 80,
1045
+ height: 32,
1046
+ filled: true,
1047
+ className: trend === "up" ? "text-green-500" : trend === "down" ? "text-red-500" : "text-accent"
1048
+ })]
1049
+ })]
1050
+ });
1051
+ });
1052
+ MetricCard.displayName = "MetricCard";
1053
+
1054
+ //#endregion
1055
+ //#region src/components/data-display/timeline.tsx
1056
+ const timelineVariants = cva("relative", {
1057
+ variants: { orientation: {
1058
+ vertical: "flex flex-col",
1059
+ horizontal: "flex flex-row"
1060
+ } },
1061
+ defaultVariants: { orientation: "vertical" }
1062
+ });
1063
+ const Timeline = React.forwardRef(({ className, orientation = "vertical", children,...props }, ref) => {
1064
+ return /* @__PURE__ */ jsx("div", {
1065
+ ref,
1066
+ className: cn(timelineVariants({
1067
+ orientation,
1068
+ className
1069
+ })),
1070
+ ...props,
1071
+ children
1072
+ });
1073
+ });
1074
+ Timeline.displayName = "Timeline";
1075
+ const timelineItemVariants = cva("relative flex", {
1076
+ variants: { orientation: {
1077
+ vertical: "flex-row gap-4 pb-8 last:pb-0",
1078
+ horizontal: "flex-col gap-2 pr-8 last:pr-0"
1079
+ } },
1080
+ defaultVariants: { orientation: "vertical" }
1081
+ });
1082
+ const TimelineItem = React.forwardRef(({ className, orientation = "vertical", active, children,...props }, ref) => {
1083
+ return /* @__PURE__ */ jsx("div", {
1084
+ ref,
1085
+ className: cn(timelineItemVariants({
1086
+ orientation,
1087
+ className
1088
+ })),
1089
+ "data-active": active,
1090
+ ...props,
1091
+ children
1092
+ });
1093
+ });
1094
+ TimelineItem.displayName = "TimelineItem";
1095
+ const timelineIndicatorVariants = cva("flex items-center justify-center rounded-full border-2 shrink-0", {
1096
+ variants: {
1097
+ size: {
1098
+ sm: "h-3 w-3",
1099
+ md: "h-4 w-4",
1100
+ lg: "h-6 w-6"
1101
+ },
1102
+ variant: {
1103
+ default: "border-border bg-surface",
1104
+ primary: "border-accent bg-accent",
1105
+ success: "border-green-500 bg-green-500",
1106
+ warning: "border-amber-500 bg-amber-500",
1107
+ error: "border-red-500 bg-red-500",
1108
+ info: "border-blue-500 bg-blue-500",
1109
+ muted: "border-muted-foreground bg-muted"
1110
+ }
1111
+ },
1112
+ defaultVariants: {
1113
+ size: "md",
1114
+ variant: "default"
1115
+ }
1116
+ });
1117
+ const TimelineIndicator = React.forwardRef(({ className, size, variant, showLine = true, linePosition = "after", orientation = "vertical", children,...props }, ref) => {
1118
+ const isVertical = orientation === "vertical";
1119
+ return /* @__PURE__ */ jsxs("div", {
1120
+ ref,
1121
+ className: cn("relative flex items-center", isVertical ? "flex-col" : "flex-row"),
1122
+ children: [
1123
+ showLine && (linePosition === "before" || linePosition === "both") && /* @__PURE__ */ jsx("div", { className: cn("bg-border", isVertical ? "w-0.5 flex-1" : "h-0.5 flex-1") }),
1124
+ /* @__PURE__ */ jsx("div", {
1125
+ className: cn(timelineIndicatorVariants({
1126
+ size,
1127
+ variant,
1128
+ className
1129
+ })),
1130
+ ...props,
1131
+ children
1132
+ }),
1133
+ showLine && (linePosition === "after" || linePosition === "both") && /* @__PURE__ */ jsx("div", { className: cn("bg-border", isVertical ? "w-0.5 flex-1" : "h-0.5 flex-1") })
1134
+ ]
1135
+ });
1136
+ });
1137
+ TimelineIndicator.displayName = "TimelineIndicator";
1138
+ const TimelineConnector = React.forwardRef(({ className, orientation = "vertical",...props }, ref) => {
1139
+ const isVertical = orientation === "vertical";
1140
+ return /* @__PURE__ */ jsx("div", {
1141
+ ref,
1142
+ className: cn("bg-border", isVertical ? "absolute left-[7px] top-4 bottom-0 w-0.5" : "absolute top-[7px] left-4 right-0 h-0.5", className),
1143
+ ...props
1144
+ });
1145
+ });
1146
+ TimelineConnector.displayName = "TimelineConnector";
1147
+ const TimelineContent = React.forwardRef(({ className, children,...props }, ref) => {
1148
+ return /* @__PURE__ */ jsx("div", {
1149
+ ref,
1150
+ className: cn("flex-1 pt-0.5", className),
1151
+ ...props,
1152
+ children
1153
+ });
1154
+ });
1155
+ TimelineContent.displayName = "TimelineContent";
1156
+ const TimelineTitle = React.forwardRef(({ className, children,...props }, ref) => {
1157
+ return /* @__PURE__ */ jsx("h4", {
1158
+ ref,
1159
+ className: cn("text-sm font-medium text-foreground", className),
1160
+ ...props,
1161
+ children
1162
+ });
1163
+ });
1164
+ TimelineTitle.displayName = "TimelineTitle";
1165
+ const TimelineDescription = React.forwardRef(({ className, children,...props }, ref) => {
1166
+ return /* @__PURE__ */ jsx("p", {
1167
+ ref,
1168
+ className: cn("text-sm text-muted-foreground", className),
1169
+ ...props,
1170
+ children
1171
+ });
1172
+ });
1173
+ TimelineDescription.displayName = "TimelineDescription";
1174
+ const TimelineTime = React.forwardRef(({ className, children,...props }, ref) => {
1175
+ return /* @__PURE__ */ jsx("span", {
1176
+ ref,
1177
+ className: cn("text-xs text-muted-foreground", className),
1178
+ ...props,
1179
+ children
1180
+ });
1181
+ });
1182
+ TimelineTime.displayName = "TimelineTime";
1183
+
1184
+ //#endregion
1185
+ export { AreaTimeSeriesChart, BarListChart, DataTable, JsonViewer, LatencyPercentilesChart, MetricCard, SparkBar, Sparkline, StatusDistributionChart, TimeRangeSelector, Timeline, TimelineConnector, TimelineContent, TimelineDescription, TimelineIndicator, TimelineItem, TimelineTime, TimelineTitle, createTimeRange, timelineIndicatorVariants, timelineItemVariants, timelineVariants };
1186
+ //# sourceMappingURL=data-display-IcuThGEY.mjs.map