@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,117 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { useChartContext } from "./chart-container.mjs";
4
+ import { ArrowDown, ArrowUp } from "lucide-react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { cva } from "class-variance-authority";
7
+ import * as React$1 from "react";
8
+ import { Area, AreaChart, ResponsiveContainer } from "recharts";
9
+ //#region src/components/stat.tsx
10
+ const statDeltaVariants = cva("inline-flex items-center gap-0.5 rounded-md px-1.5 py-0.5 font-mono text-[11px] font-medium leading-none", {
11
+ variants: { sentiment: {
12
+ positive: "text-success bg-success/12",
13
+ negative: "text-destructive bg-destructive/12"
14
+ } },
15
+ defaultVariants: { sentiment: "positive" }
16
+ });
17
+ const toSparkData = (sparkline) => (sparkline ?? []).map((point, index) => typeof point === "number" ? {
18
+ index,
19
+ value: point
20
+ } : {
21
+ index,
22
+ value: point.value
23
+ });
24
+ const SEMANTIC_KEY = {
25
+ error: "destructive",
26
+ warning: "warning",
27
+ success: "success"
28
+ };
29
+ function Stat({ value, unit, delta, sparkline, semantic, className, ...props }) {
30
+ const { palette, theme } = useChartContext();
31
+ const gradientId = React$1.useId().replace(/:/g, "");
32
+ const sparkData = React$1.useMemo(() => toSparkData(sparkline), [sparkline]);
33
+ const hasSpark = sparkData.some((point) => point.value > 0);
34
+ const sparkColor = semantic ? theme[SEMANTIC_KEY[semantic]] : palette[0];
35
+ const sentiment = delta && (delta.invert ? delta.direction === "down" : delta.direction === "up") ? "positive" : "negative";
36
+ return /* @__PURE__ */ jsxs("div", {
37
+ "data-slot": "stat",
38
+ className: cn("flex flex-col gap-2.5", className),
39
+ ...props,
40
+ children: [/* @__PURE__ */ jsxs("div", {
41
+ className: "flex items-baseline gap-3",
42
+ children: [
43
+ /* @__PURE__ */ jsx("span", {
44
+ className: "type-display-sm font-bold leading-none tracking-tight tabular-nums text-foreground",
45
+ children: value
46
+ }),
47
+ unit && /* @__PURE__ */ jsx("span", {
48
+ className: "font-mono text-[11px] leading-none text-quaternary-foreground mb-0.5",
49
+ children: unit
50
+ }),
51
+ delta && /* @__PURE__ */ jsxs(DeltaPill, {
52
+ sentiment,
53
+ className: "mb-0.5",
54
+ children: [delta.direction === "up" ? /* @__PURE__ */ jsx(ArrowUp, { className: "size-3" }) : /* @__PURE__ */ jsx(ArrowDown, { className: "size-3" }), delta.label ?? `${delta.value}%`]
55
+ })
56
+ ]
57
+ }), hasSpark && /* @__PURE__ */ jsx("div", {
58
+ className: "h-9 w-full",
59
+ children: /* @__PURE__ */ jsx(ResponsiveContainer, {
60
+ width: "100%",
61
+ height: "100%",
62
+ initialDimension: {
63
+ width: 0,
64
+ height: 36
65
+ },
66
+ children: /* @__PURE__ */ jsxs(AreaChart, {
67
+ data: sparkData,
68
+ margin: {
69
+ top: 4,
70
+ right: 2,
71
+ bottom: 0,
72
+ left: 2
73
+ },
74
+ children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", {
75
+ id: gradientId,
76
+ x1: "0",
77
+ y1: "0",
78
+ x2: "0",
79
+ y2: "1",
80
+ children: [/* @__PURE__ */ jsx("stop", {
81
+ offset: "0%",
82
+ stopColor: sparkColor,
83
+ stopOpacity: .4
84
+ }), /* @__PURE__ */ jsx("stop", {
85
+ offset: "100%",
86
+ stopColor: sparkColor,
87
+ stopOpacity: 0
88
+ })]
89
+ }) }), /* @__PURE__ */ jsx(Area, {
90
+ type: "monotone",
91
+ dataKey: "value",
92
+ stroke: sparkColor,
93
+ strokeWidth: 1.6,
94
+ fill: `url(#${gradientId})`,
95
+ isAnimationActive: false,
96
+ dot: ({ cx, cy, index }) => {
97
+ return index === sparkData.length - 1 && cx != null && cy != null ? /* @__PURE__ */ jsx("circle", {
98
+ cx,
99
+ cy,
100
+ r: 2.5,
101
+ fill: sparkColor
102
+ }, index) : /* @__PURE__ */ jsx("g", {}, index);
103
+ }
104
+ })]
105
+ })
106
+ })
107
+ })]
108
+ });
109
+ }
110
+ function DeltaPill({ sentiment, className, ...props }) {
111
+ return /* @__PURE__ */ jsx("span", {
112
+ className: cn(statDeltaVariants({ sentiment }), className),
113
+ ...props
114
+ });
115
+ }
116
+ //#endregion
117
+ export { Stat, statDeltaVariants };
@@ -1,24 +1,6 @@
1
1
  import * as React$1 from "react";
2
2
 
3
3
  //#region src/components/wizard.d.ts
4
- interface WizardStep {
5
- id: string;
6
- label: string;
7
- }
8
- interface WizardStepsProps {
9
- steps: readonly WizardStep[];
10
- activeIdx: number;
11
- onSelect: (idx: number) => void;
12
- ariaLabel?: string;
13
- className?: string;
14
- }
15
- declare function WizardSteps({
16
- steps,
17
- activeIdx,
18
- onSelect,
19
- ariaLabel,
20
- className
21
- }: WizardStepsProps): React$1.JSX.Element;
22
4
  interface WizardProgressProps extends React$1.ComponentProps<"div"> {
23
5
  current: number;
24
6
  total: number;
@@ -30,4 +12,4 @@ declare function WizardProgress({
30
12
  ...props
31
13
  }: WizardProgressProps): React$1.JSX.Element;
32
14
  //#endregion
33
- export { WizardProgress, type WizardStep, WizardSteps };
15
+ export { WizardProgress };
@@ -1,25 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.mjs";
3
- import { TabsNav, TabsNavList, TabsNavTrigger } from "./tabs.mjs";
4
3
  import { jsx, jsxs } from "react/jsx-runtime";
5
4
  //#region src/components/wizard.tsx
6
- function WizardSteps({ steps, activeIdx, onSelect, ariaLabel = "Wizard steps", className }) {
7
- return /* @__PURE__ */ jsx(TabsNav, {
8
- orientation: "vertical",
9
- "aria-label": ariaLabel,
10
- className,
11
- children: /* @__PURE__ */ jsx(TabsNavList, { children: steps.map((step, idx) => /* @__PURE__ */ jsx(TabsNavTrigger, {
12
- active: idx === activeIdx,
13
- asChild: true,
14
- children: /* @__PURE__ */ jsx("button", {
15
- type: "button",
16
- onClick: () => onSelect(idx),
17
- className: "w-full justify-start text-left",
18
- children: step.label
19
- })
20
- }, step.id)) })
21
- });
22
- }
23
5
  function WizardProgress({ current, total, className, ...props }) {
24
6
  const percent = total > 0 ? Math.round(current / total * 100) : 0;
25
7
  return /* @__PURE__ */ jsxs("div", {
@@ -43,4 +25,4 @@ function WizardProgress({ current, total, className, ...props }) {
43
25
  });
44
26
  }
45
27
  //#endregion
46
- export { WizardProgress, WizardSteps };
28
+ export { WizardProgress };
@@ -0,0 +1,18 @@
1
+ //#region src/hooks/use-chart-theme.d.ts
2
+ interface ChartTheme {
3
+ foreground: string;
4
+ mutedForeground: string;
5
+ axisForeground: string;
6
+ grid: string;
7
+ border: string;
8
+ card: string;
9
+ popover: string;
10
+ destructive: string;
11
+ warning: string;
12
+ success: string;
13
+ fontMono: string;
14
+ isDark: boolean;
15
+ }
16
+ declare function useChartTheme(): ChartTheme;
17
+ //#endregion
18
+ export { ChartTheme, useChartTheme };
@@ -0,0 +1,57 @@
1
+ "use client";
2
+ import * as React$1 from "react";
3
+ //#region src/hooks/use-chart-theme.ts
4
+ const TOKEN_MAP = {
5
+ foreground: "--color-foreground",
6
+ mutedForeground: "--color-muted-foreground",
7
+ axisForeground: "--color-quaternary-foreground",
8
+ grid: "--color-sidebar-border",
9
+ border: "--color-border",
10
+ card: "--color-card",
11
+ popover: "--color-popover",
12
+ destructive: "--color-destructive",
13
+ warning: "--color-warning",
14
+ success: "--color-success",
15
+ fontMono: "--font-mono"
16
+ };
17
+ const FALLBACK = {
18
+ foreground: "#121e1e",
19
+ mutedForeground: "#3a4848",
20
+ axisForeground: "#6f7f7f",
21
+ grid: "#e3eaea",
22
+ border: "#acb8b8",
23
+ card: "#f8fafa",
24
+ popover: "#ffffff",
25
+ destructive: "#d92d20",
26
+ warning: "#dc6803",
27
+ success: "#079455",
28
+ fontMono: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
29
+ isDark: false
30
+ };
31
+ const readTheme = () => {
32
+ if (typeof window === "undefined") return FALLBACK;
33
+ const styles = window.getComputedStyle(document.documentElement);
34
+ const entries = Object.entries(TOKEN_MAP).map(([key, token]) => {
35
+ return [key, styles.getPropertyValue(token).trim() || FALLBACK[key]];
36
+ });
37
+ return {
38
+ ...Object.fromEntries(entries),
39
+ isDark: document.documentElement.classList.contains("dark")
40
+ };
41
+ };
42
+ function useChartTheme() {
43
+ const [theme, setTheme] = React$1.useState(readTheme);
44
+ React$1.useEffect(() => {
45
+ const update = () => setTheme(readTheme());
46
+ update();
47
+ const observer = new MutationObserver(update);
48
+ observer.observe(document.documentElement, {
49
+ attributes: true,
50
+ attributeFilter: ["class"]
51
+ });
52
+ return () => observer.disconnect();
53
+ }, []);
54
+ return theme;
55
+ }
56
+ //#endregion
57
+ export { useChartTheme };
@@ -0,0 +1,4 @@
1
+ //#region src/hooks/use-reduced-motion.d.ts
2
+ declare function useReducedMotion(): boolean;
3
+ //#endregion
4
+ export { useReducedMotion };
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import * as React$1 from "react";
3
+ //#region src/hooks/use-reduced-motion.ts
4
+ function useReducedMotion() {
5
+ const [reduced, setReduced] = React$1.useState(false);
6
+ React$1.useEffect(() => {
7
+ const query = window.matchMedia("(prefers-reduced-motion: reduce)");
8
+ const update = () => setReduced(query.matches);
9
+ update();
10
+ query.addEventListener("change", update);
11
+ return () => query.removeEventListener("change", update);
12
+ }, []);
13
+ return reduced;
14
+ }
15
+ //#endregion
16
+ export { useReducedMotion };
@@ -0,0 +1,4 @@
1
+ //#region src/lib/chart-palette.d.ts
2
+ type ChartPaletteName = "magenta" | "cyan";
3
+ //#endregion
4
+ export { ChartPaletteName };
@@ -0,0 +1,95 @@
1
+ const CHART_PALETTES = {
2
+ magenta: [
3
+ "#e90060",
4
+ "#ff7eb6",
5
+ "#9b5de5",
6
+ "#5b8def",
7
+ "#36c5f0",
8
+ "#6eece7",
9
+ "#d98a3d",
10
+ "#2bb6a3"
11
+ ],
12
+ cyan: [
13
+ "#17b8cf",
14
+ "#41ddc9",
15
+ "#3f8ff0",
16
+ "#8b6cf0",
17
+ "#c46bf0",
18
+ "#ff7eb6",
19
+ "#e90060",
20
+ "#c98be0"
21
+ ]
22
+ };
23
+ const heatRampMagenta = (empty) => [
24
+ empty,
25
+ "#5b0a31",
26
+ "#a3034a",
27
+ "#e90060",
28
+ "#ff7eb6"
29
+ ];
30
+ const heatRampMint = (empty) => [
31
+ empty,
32
+ "#0c4a52",
33
+ "#17b8cf",
34
+ "#41ddc9",
35
+ "#6eece7"
36
+ ];
37
+ const HEAT_EMPTY = {
38
+ light: "#eef3f3",
39
+ dark: "#102222"
40
+ };
41
+ const HEAT_RAMPS = {
42
+ magenta: heatRampMagenta,
43
+ cyan: heatRampMint
44
+ };
45
+ const heatRamp = (palette, empty) => HEAT_RAMPS[palette](empty);
46
+ const hexToRgb = (hex) => {
47
+ const value = Number.parseInt(hex.slice(1), 16);
48
+ return [
49
+ value >> 16 & 255,
50
+ value >> 8 & 255,
51
+ value & 255
52
+ ];
53
+ };
54
+ const luminance = (hex) => {
55
+ const linear = hexToRgb(hex).map((channel) => {
56
+ const normalized = channel / 255;
57
+ return normalized <= .03928 ? normalized / 12.92 : ((normalized + .055) / 1.055) ** 2.4;
58
+ });
59
+ return .2126 * linear[0] + .7152 * linear[1] + .0722 * linear[2];
60
+ };
61
+ const paletteColor = (palette, index) => {
62
+ return palette[(index % palette.length + palette.length) % palette.length];
63
+ };
64
+ const RAMP_ENDS = {
65
+ magenta: ["#e90060", "#ff7eb6"],
66
+ cyan: ["#17b8cf", "#6eece7"]
67
+ };
68
+ const mixHex = (from, to, fraction) => {
69
+ const [fromR, fromG, fromB] = hexToRgb(from);
70
+ const [toR, toG, toB] = hexToRgb(to);
71
+ const ratio = Math.min(1, Math.max(0, fraction));
72
+ const channel = (start, end) => Math.round(start + (end - start) * ratio);
73
+ return `#${[
74
+ channel(fromR, toR),
75
+ channel(fromG, toG),
76
+ channel(fromB, toB)
77
+ ].map((value) => value.toString(16).padStart(2, "0")).join("")}`;
78
+ };
79
+ const rampColor = (palette, fraction) => {
80
+ const [from, to] = RAMP_ENDS[palette];
81
+ return mixHex(from, to, fraction);
82
+ };
83
+ /**
84
+ * Interpolate continuously across a multi-stop heat ramp (e.g. `heatRampMagenta`),
85
+ * so a normalized 0..1 value reads as a smooth single-hue gradient rather than
86
+ * the five discrete bands.
87
+ */
88
+ const heatColor = (stops, fraction) => {
89
+ const clamped = Math.min(1, Math.max(0, fraction));
90
+ const segment = (stops.length - 1) * clamped;
91
+ const lowerIndex = Math.min(stops.length - 2, Math.floor(segment));
92
+ return mixHex(stops[lowerIndex], stops[lowerIndex + 1], segment - lowerIndex);
93
+ };
94
+ //#endregion
95
+ export { CHART_PALETTES, HEAT_EMPTY, heatColor, heatRamp, luminance, paletteColor, rampColor };
@@ -0,0 +1,14 @@
1
+ //#region src/lib/chart.d.ts
2
+ /**
3
+ * Declarative description of one plotted series. The same shape drives area,
4
+ * line and bar charts — what differs is how each chart renders it.
5
+ */
6
+ interface ChartSeries {
7
+ key: string;
8
+ name?: string;
9
+ color?: string;
10
+ semantic?: "error" | "warning" | "success";
11
+ dashed?: boolean;
12
+ }
13
+ //#endregion
14
+ export { ChartSeries };
@@ -0,0 +1,42 @@
1
+ import { luminance, paletteColor } from "./chart-palette.mjs";
2
+ import * as React$1 from "react";
3
+ //#region src/lib/chart.ts
4
+ const formatShare = (fraction) => `${(fraction * 100).toFixed(fraction >= .1 ? 0 : 1)}%`;
5
+ const semanticColor = (theme, semantic) => {
6
+ if (semantic === "error") return theme.destructive;
7
+ if (semantic === "warning") return theme.warning;
8
+ return theme.success;
9
+ };
10
+ /**
11
+ * Resolve each series to a concrete color and name. Color precedence:
12
+ * explicit `color` → `semantic` token → palette slot by declared index (so the
13
+ * lead series keeps the lead color even after the bands are reordered).
14
+ */
15
+ const resolveSeries = (series, palette, theme) => series.map((entry, index) => ({
16
+ ...entry,
17
+ name: entry.name ?? entry.key,
18
+ color: entry.color ?? (entry.semantic ? semanticColor(theme, entry.semantic) : paletteColor(palette, index))
19
+ }));
20
+ /**
21
+ * Stacked bands read cleanest as a vertical gradient: darkest at the baseline,
22
+ * lightest at the top edge. Sorting by luminance enforces that for any palette
23
+ * (this is what fixed the "muddy cyan" stack in the lab). Render order maps to
24
+ * stack order in Recharts — first entry sits at the bottom.
25
+ */
26
+ const orderByLuminance = (series) => [...series].sort((lower, upper) => luminance(lower.color) - luminance(upper.color));
27
+ const makeXAxisTick = (theme) => ({ x, y, payload, index, visibleTicksCount }) => {
28
+ const isFirst = index === 0;
29
+ const isLast = visibleTicksCount != null && index === visibleTicksCount - 1;
30
+ const anchor = isFirst ? "start" : isLast ? "end" : "middle";
31
+ return React$1.createElement("text", {
32
+ x: Number(x ?? 0),
33
+ y: Number(y ?? 0),
34
+ dy: 12,
35
+ textAnchor: anchor,
36
+ fill: theme.axisForeground,
37
+ fontFamily: theme.fontMono,
38
+ fontSize: 10
39
+ }, String(payload?.value ?? ""));
40
+ };
41
+ //#endregion
42
+ export { formatShare, makeXAxisTick, orderByLuminance, resolveSeries };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpic-ai/ui",
3
- "version": "0.0.0-dev.g00dcac1",
3
+ "version": "0.0.0-dev.g014cfc8",
4
4
  "description": "Alpic design system — shared UI components",
5
5
  "type": "module",
6
6
  "exports": {
@@ -23,35 +23,36 @@
23
23
  "src"
24
24
  ],
25
25
  "peerDependencies": {
26
- "lucide-react": "^1.18.0",
26
+ "lucide-react": "^1.21.0",
27
27
  "react": "^19.2.7",
28
28
  "react-dom": "^19.2.7",
29
- "react-hook-form": "^7.79.0",
29
+ "react-hook-form": "^7.80.0",
30
30
  "sonner": "^2.0.7",
31
31
  "tailwindcss": "^4.3.1",
32
32
  "tw-animate-css": "^1.4.0"
33
33
  },
34
34
  "dependencies": {
35
- "@radix-ui/react-accordion": "^1.2.13",
36
- "@radix-ui/react-avatar": "^1.1.12",
37
- "@radix-ui/react-checkbox": "^1.3.4",
38
- "@radix-ui/react-collapsible": "^1.1.13",
39
- "@radix-ui/react-dialog": "^1.1.16",
40
- "@radix-ui/react-dropdown-menu": "^2.1.17",
41
- "@radix-ui/react-label": "^2.1.9",
42
- "@radix-ui/react-popover": "^1.1.16",
43
- "@radix-ui/react-radio-group": "^1.4.0",
44
- "@radix-ui/react-scroll-area": "^1.2.11",
45
- "@radix-ui/react-select": "^2.3.0",
46
- "@radix-ui/react-separator": "^1.1.9",
47
- "@radix-ui/react-slot": "^1.2.5",
48
- "@radix-ui/react-switch": "^1.3.0",
49
- "@radix-ui/react-tabs": "^1.1.14",
50
- "@radix-ui/react-toggle-group": "^1.1.12",
51
- "@radix-ui/react-tooltip": "^1.2.9",
35
+ "@radix-ui/react-accordion": "^1.2.14",
36
+ "@radix-ui/react-avatar": "^1.2.0",
37
+ "@radix-ui/react-checkbox": "^1.3.5",
38
+ "@radix-ui/react-collapsible": "^1.1.14",
39
+ "@radix-ui/react-dialog": "^1.1.17",
40
+ "@radix-ui/react-dropdown-menu": "^2.1.18",
41
+ "@radix-ui/react-label": "^2.1.10",
42
+ "@radix-ui/react-popover": "^1.1.17",
43
+ "@radix-ui/react-radio-group": "^1.4.1",
44
+ "@radix-ui/react-scroll-area": "^1.2.12",
45
+ "@radix-ui/react-select": "^2.3.1",
46
+ "@radix-ui/react-separator": "^1.1.10",
47
+ "@radix-ui/react-slot": "^1.3.0",
48
+ "@radix-ui/react-switch": "^1.3.1",
49
+ "@radix-ui/react-tabs": "^1.1.15",
50
+ "@radix-ui/react-toggle-group": "^1.1.13",
51
+ "@radix-ui/react-tooltip": "^1.2.10",
52
52
  "class-variance-authority": "^0.7.1",
53
53
  "clsx": "^2.1.1",
54
54
  "cmdk": "^1.1.1",
55
+ "recharts": "^3.8.1",
55
56
  "tailwind-merge": "^3.6.0"
56
57
  },
57
58
  "devDependencies": {
@@ -59,12 +60,12 @@
59
60
  "@tailwindcss/postcss": "^4.3.1",
60
61
  "@types/react": "19.2.17",
61
62
  "@types/react-dom": "19.2.3",
62
- "lucide-react": "^1.18.0",
63
- "react-hook-form": "^7.79.0",
63
+ "lucide-react": "^1.21.0",
64
+ "react-hook-form": "^7.80.0",
64
65
  "shx": "^0.4.0",
65
66
  "sonner": "^2.0.7",
66
67
  "tailwindcss": "^4.3.1",
67
- "tsdown": "^0.22.2",
68
+ "tsdown": "^0.22.3",
68
69
  "tw-animate-css": "^1.4.0",
69
70
  "typescript": "^6.0.3"
70
71
  },